From 3034ede3a6fb342384c3b33d19caca3ecf9531b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Fr=C3=B6schle?= Date: Thu, 2 Jan 2014 21:33:27 +0000 Subject: [PATCH] implemented PHY, but still only occasionly transmitted packets. Obviously, there's a bug somewhere ;) --- Makefile | 3 +- bas.lk.in | 1 + dma/dma.c | 80 ++++++----------- include/am79c874.h | 85 +++++++++++++++++++ include/dma.h | 3 +- include/driver_mem.h | 6 +- include/driver_vec.h | 39 ++++----- net/am79c874.c | 114 +++++++++++++++++++++++++ net/fec.c | 23 +++-- net/fecbd.c | 198 ++++++++++++++++++++++--------------------- pci/pci.c | 4 +- sys/BaS.c | 3 +- sys/driver_mem.c | 5 +- sys/exceptions.S | 43 +++++----- 14 files changed, 396 insertions(+), 211 deletions(-) create mode 100644 include/am79c874.h create mode 100644 net/am79c874.c diff --git a/Makefile b/Makefile index a979756..66c4818 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ # can be either "Y" or "N" (without quotes). "Y" for using the m68k-elf-, "N" for using the m68k-atari-mint # toolchain -COMPILE_ELF=Y +COMPILE_ELF=N ifeq (Y,$(COMPILE_ELF)) TCPREFIX=m68k-elf- @@ -93,6 +93,7 @@ CSRCS= \ nbuf.c \ queue.c \ net_timer.c \ + am79c874.c \ nif.c \ fecbd.c \ fec.c \ diff --git a/bas.lk.in b/bas.lk.in index 994ea18..1653d06 100644 --- a/bas.lk.in +++ b/bas.lk.in @@ -59,6 +59,7 @@ SECTIONS OBJDIR/nif.o(.text) OBJDIR/fecbd.o(.text) OBJDIR/fec.o(.text) + OBJDIR/am79c874.o(.text) OBJDIR/ip.o(.text) OBJDIR/udp.o(text) OBJDIR/bootp.o(text) diff --git a/dma/dma.c b/dma/dma.c index 8886699..58416d1 100644 --- a/dma/dma.c +++ b/dma/dma.c @@ -131,40 +131,34 @@ int dma_set_initiator(int initiator) break; case DMA_FEC0_RX: - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC16(3)) - | MCF_DMA_IMCR_IMC16_FEC0RX; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC16(3)) | MCF_DMA_IMCR_IMC16_FEC0RX; used_reqs[16] = DMA_FEC0_RX; break; case DMA_FEC0_TX: - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC17(3)) - | MCF_DMA_IMCR_IMC17_FEC0TX; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC17(3)) | MCF_DMA_IMCR_IMC17_FEC0TX; used_reqs[17] = DMA_FEC0_TX; break; case DMA_FEC1_RX: - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC20(3)) - | MCF_DMA_IMCR_IMC20_FEC1RX; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC20(3)) | MCF_DMA_IMCR_IMC20_FEC1RX; used_reqs[20] = DMA_FEC1_RX; break; case DMA_FEC1_TX: if (used_reqs[21] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC21(3)) - | MCF_DMA_IMCR_IMC21_FEC1TX; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC21(3)) | MCF_DMA_IMCR_IMC21_FEC1TX; used_reqs[21] = DMA_FEC1_TX; } else if (used_reqs[25] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC25(3)) - | MCF_DMA_IMCR_IMC25_FEC1TX; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC25(3)) | MCF_DMA_IMCR_IMC25_FEC1TX; used_reqs[25] = DMA_FEC1_TX; } else if (used_reqs[31] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC31(3)) - | MCF_DMA_IMCR_IMC31_FEC1TX; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC31(3)) | MCF_DMA_IMCR_IMC31_FEC1TX; used_reqs[31] = DMA_FEC1_TX; } else /* No empty slots */ @@ -178,14 +172,12 @@ int dma_set_initiator(int initiator) case DMA_DREQ1: if (used_reqs[29] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC29(3)) - | MCF_DMA_IMCR_IMC29_DREQ1; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC29(3)) | MCF_DMA_IMCR_IMC29_DREQ1; used_reqs[29] = DMA_DREQ1; } else if (used_reqs[21] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC21(3)) - | MCF_DMA_IMCR_IMC21_DREQ1; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC21(3)) | MCF_DMA_IMCR_IMC21_DREQ1; used_reqs[21] = DMA_DREQ1; } else /* No empty slots */ @@ -199,8 +191,7 @@ int dma_set_initiator(int initiator) case DMA_CTM0: if (used_reqs[24] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC24(3)) - | MCF_DMA_IMCR_IMC24_CTM0; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC24(3)) | MCF_DMA_IMCR_IMC24_CTM0; used_reqs[24] = DMA_CTM0; } else /* No empty slots */ @@ -214,8 +205,7 @@ int dma_set_initiator(int initiator) case DMA_CTM1: if (used_reqs[25] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC25(3)) - | MCF_DMA_IMCR_IMC25_CTM1; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC25(3)) | MCF_DMA_IMCR_IMC25_CTM1; used_reqs[25] = DMA_CTM1; } else /* No empty slots */ @@ -229,8 +219,7 @@ int dma_set_initiator(int initiator) case DMA_CTM2: if (used_reqs[26] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC26(3)) - | MCF_DMA_IMCR_IMC26_CTM2; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC26(3)) | MCF_DMA_IMCR_IMC26_CTM2; used_reqs[26] = DMA_CTM2; } else /* No empty slots */ @@ -244,8 +233,7 @@ int dma_set_initiator(int initiator) case DMA_CTM3: if (used_reqs[27] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC27(3)) - | MCF_DMA_IMCR_IMC27_CTM3; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC27(3)) | MCF_DMA_IMCR_IMC27_CTM3; used_reqs[27] = DMA_CTM3; } else /* No empty slots */ @@ -259,8 +247,7 @@ int dma_set_initiator(int initiator) case DMA_CTM4: if (used_reqs[28] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC28(3)) - | MCF_DMA_IMCR_IMC28_CTM4; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC28(3)) | MCF_DMA_IMCR_IMC28_CTM4; used_reqs[28] = DMA_CTM4; } else /* No empty slots */ @@ -274,8 +261,7 @@ int dma_set_initiator(int initiator) case DMA_CTM5: if (used_reqs[29] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC29(3)) - | MCF_DMA_IMCR_IMC29_CTM5; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC29(3)) | MCF_DMA_IMCR_IMC29_CTM5; used_reqs[29] = DMA_CTM5; } else /* No empty slots */ @@ -289,8 +275,7 @@ int dma_set_initiator(int initiator) case DMA_CTM6: if (used_reqs[30] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC30(3)) - | MCF_DMA_IMCR_IMC30_CTM6; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC30(3)) | MCF_DMA_IMCR_IMC30_CTM6; used_reqs[30] = DMA_CTM6; } else /* No empty slots */ @@ -304,8 +289,7 @@ int dma_set_initiator(int initiator) case DMA_CTM7: if (used_reqs[31] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC31(3)) - | MCF_DMA_IMCR_IMC31_CTM7; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC31(3)) | MCF_DMA_IMCR_IMC31_CTM7; used_reqs[31] = DMA_CTM7; } else /* No empty slots */ @@ -319,8 +303,7 @@ int dma_set_initiator(int initiator) case DMA_USBEP4: if (used_reqs[26] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC26(3)) - | MCF_DMA_IMCR_IMC26_USBEP4; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC26(3)) | MCF_DMA_IMCR_IMC26_USBEP4; used_reqs[26] = DMA_USBEP4; } else /* No empty slots */ @@ -334,8 +317,7 @@ int dma_set_initiator(int initiator) case DMA_USBEP5: if (used_reqs[27] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC27(3)) - | MCF_DMA_IMCR_IMC27_USBEP5; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC27(3)) | MCF_DMA_IMCR_IMC27_USBEP5; used_reqs[27] = DMA_USBEP5; } else /* No empty slots */ @@ -349,8 +331,7 @@ int dma_set_initiator(int initiator) case DMA_USBEP6: if (used_reqs[28] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC28(3)) - | MCF_DMA_IMCR_IMC28_USBEP6; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC28(3)) | MCF_DMA_IMCR_IMC28_USBEP6; used_reqs[28] = DMA_USBEP6; } else /* No empty slots */ @@ -359,8 +340,7 @@ int dma_set_initiator(int initiator) case DMA_PSC2_RX: if (used_reqs[28] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC28(3)) - | MCF_DMA_IMCR_IMC28_PSC2RX; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC28(3)) | MCF_DMA_IMCR_IMC28_PSC2RX; used_reqs[28] = DMA_PSC2_RX; } else /* No empty slots */ { @@ -373,8 +353,7 @@ int dma_set_initiator(int initiator) case DMA_PSC2_TX: if (used_reqs[29] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC29(3)) - | MCF_DMA_IMCR_IMC29_PSC2TX; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC29(3)) | MCF_DMA_IMCR_IMC29_PSC2TX; used_reqs[29] = DMA_PSC2_TX; } else /* No empty slots */ @@ -388,8 +367,7 @@ int dma_set_initiator(int initiator) case DMA_PSC3_RX: if (used_reqs[30] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC30(3)) - | MCF_DMA_IMCR_IMC30_PSC3RX; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC30(3)) | MCF_DMA_IMCR_IMC30_PSC3RX; used_reqs[30] = DMA_PSC3_RX; } else /* No empty slots */ @@ -403,8 +381,7 @@ int dma_set_initiator(int initiator) case DMA_PSC3_TX: if (used_reqs[31] == 0) { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC31(3)) - | MCF_DMA_IMCR_IMC31_PSC3TX; + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC31(3)) | MCF_DMA_IMCR_IMC31_PSC3TX; used_reqs[31] = DMA_PSC3_TX; } else /* No empty slots */ @@ -565,12 +542,10 @@ void dma_free_channel(int requestor) int dma_interrupt_handler(void *arg1, void *arg2) { uint32_t i, interrupts; - uint32_t ipl; - (void)arg1; - (void)arg2; + dbg("%s: arg1 = %p, arg2 = %p\r\n", __FUNCTION__, arg1, arg2); - ipl = set_ipl(7); + (void) set_ipl(7); /* * Determine which interrupt(s) triggered by AND'ing the @@ -591,12 +566,13 @@ int dma_interrupt_handler(void *arg1, void *arg2) { /* If there is a handler, call it */ if (dma_channel[i].handler != NULL) + { + dbg("%s: call handler for interrupt %d (%p)\r\n", __FUNCTION__, i, dma_channel[i].handler); dma_channel[i].handler(); + } } } - set_ipl(ipl); - return 1; } /********************************************************************/ diff --git a/include/am79c874.h b/include/am79c874.h new file mode 100644 index 0000000..d501183 --- /dev/null +++ b/include/am79c874.h @@ -0,0 +1,85 @@ +/* + * File: am79c874.h + * Purpose: Driver for the AM79C874 10/100 Ethernet PHY + * + * Notes: + */ + +#ifndef _AM79C874_H_ +#define _AM79C874_H_ + + +extern int am79c874_init(uint8_t fec_ch, uint8_t phy_addr, uint8_t speed, uint8_t duplex); + + +/* MII Register Addresses */ +#define MII_AM79C874_CR 0 /* MII Management Control Register */ +#define MII_AM79C874_SR 1 /* MII Management Status Register */ +#define MII_AM79C874_PHYIDR1 2 /* PHY Identifier 1 Register */ +#define MII_AM79C874_PHYIDR2 3 /* PHY Identifier 2 Register */ +#define MII_AM79C874_ANAR 4 /* Auto-Negociation Advertissement Register */ +#define MII_AM79C874_ANLPAR 5 /* Auto-Negociation Link Partner Register */ +#define MII_AM79C874_ANER 6 /* Auto-Negociation Expansion Register */ +#define MII_AM79C874_ANNPTR 7 /* Next Page Advertisement Register */ +#define MII_AM79C874_MFR 16 /* Miscellaneous Feature Register */ +#define MII_AM79C874_ICSR 17 /* Interrupt/Status Register */ +#define MII_AM79C874_DR 18 /* Diagnostic Register */ +#define MII_AM79C874_PMLR 19 /* Power and Loopback Register */ +#define MII_AM79C874_MCR 21 /* ModeControl Register */ +#define MII_AM79C874_DC 23 /* Disconnect Counter */ +#define MII_AM79C874_REC 24 /* Recieve Error Counter */ + +/* Bit definitions and macros for MII_AM79C874_CR */ +#define MII_AM79C874_CR_RESET (0x8000) +#define MII_AM79C874_CR_LOOP (0x4000) +#define MII_AM79C874_CR_100MB (0x2000) +#define MII_AM79C874_CR_AUTON (0x1000) +#define MII_AM79C874_CR_POWD (0x0800) +#define MII_AM79C874_CR_ISO (0x0400) +#define MII_AM79C874_CR_RST_NEG (0x0200) +#define MII_AM79C874_CR_DPLX (0x0100) +#define MII_AM79C874_CR_COL_TST (0x0080) +#define MII_AM79C874_CR_SPEED_MASK (0x2040) +#define MII_AM79C874_CR_1000_MPS (0x0040) +#define MII_AM79C874_CR_100_MPS (0x2000) +#define MII_AM79C874_CR_10_MPS (0x0000) + +/* Bit definitions and macros for MII_AM79C874_SR */ +#define MII_AM79C874_SR_100T4 (0x8000) +#define MII_AM79C874_SR_100TXF (0x4000) +#define MII_AM79C874_SR_100TXH (0x2000) +#define MII_AM79C874_SR_10TF (0x1000) +#define MII_AM79C874_SR_10TH (0x0800) +#define MII_AM79C874_SR_PRE_SUP (0x0040) +#define MII_AM79C874_SR_AUTN_COMP (0x0020) +#define MII_AM79C874_SR_RF (0x0010) +#define MII_AM79C874_SR_AUTN_ABLE (0x0008) +#define MII_AM79C874_SR_LS (0x0004) +#define MII_AM79C874_SR_JD (0x0002) +#define MII_AM79C874_SR_EXT (0x0001) + +/* Bit definitions and macros for MII_AM79C874_ANLPAR */ +#define MII_AM79C874_ANLPAR_NP (0x8000) +#define MII_AM79C874_ANLPAR_ACK (0x4000) +#define MII_AM79C874_ANLPAR_RF (0x2000) +#define MII_AM79C874_ANLPAR_T4 (0x0200) +#define MII_AM79C874_ANLPAR_TXFD (0x0100) +#define MII_AM79C874_ANLPAR_TX (0x0080) +#define MII_AM79C874_ANLPAR_10FD (0x0040) +#define MII_AM79C874_ANLPAR_10 (0x0020) +#define MII_AM79C874_ANLPAR_100 (0x0380) +#define MII_AM79C874_ANLPAR_PSB_MASK (0x001F) +#define MII_AM79C874_ANLPAR_PSB_802_3 (0x0001) +#define MII_AM79C874_ANLPAR_PSB_802_9 (0x0002) + +/* Bit definitions and macros for MII_AM79C874_DR */ +#define MII_AM79C874_DR_DPLX (0x0800) +#define MII_AM79C874_DR_DATA_RATE (0x0400) +#define MII_AM79C874_DR_RX_PASS (0x0200) +#define MII_AM79C874_DR_RX_LOCK (0x0100) + +#define AUTONEGLINK (MII_AM79C874_SR_AUTN_COMP | MII_AM79C874_SR_LS) + +/********************************************************************/ + +#endif /* _AM79C874_H_ */ diff --git a/include/dma.h b/include/dma.h index ba22ebc..66dde5a 100644 --- a/include/dma.h +++ b/include/dma.h @@ -1,6 +1,5 @@ /* - * spidma.h - * + * spidma.h * * This file is part of BaS_gcc. * * BaS_gcc is free software: you can redistribute it and/or modify diff --git a/include/driver_mem.h b/include/driver_mem.h index 975a4c1..a08d0f3 100644 --- a/include/driver_mem.h +++ b/include/driver_mem.h @@ -1,13 +1,15 @@ #ifndef _DRIVER_MEM_H_ #define _DRIVER_MEM_H_ +#include "bas_types.h" + /* * the driver_mem module provides a block of _uncached_ memory for USB and other drivers as * well as some memory handling functions for it */ extern int driver_mem_init(void); -extern void *driver_mem_alloc(long amount); -extern int driver_mem_free(void *addr); +extern void *driver_mem_alloc(uint32_t amount); +extern int32_t driver_mem_free(void *addr); extern void driver_mem_release(void); #endif /* _DRIVER_MEM_H_ */ diff --git a/include/driver_vec.h b/include/driver_vec.h index 664babb..88c39a1 100644 --- a/include/driver_vec.h +++ b/include/driver_vec.h @@ -50,25 +50,26 @@ struct dma_driver_interface { int32_t version; int32_t magic; - int32_t (*dma_set_initiator)(int initiator); - uint32_t (*dma_get_initiator)(int requestor); - void (*dma_free_initiator)(int requestor); - int32_t (*dma_set_channel)(int requestor, void (*handler)(void)); - int (*dma_get_channel)(int requestor); - void (*dma_free_channel)(int requestor); - void (*dma_clear_channel)(int channel); - int (*MCD_startDma)(int channel, int8_t *srcAddr, int16_t srcIncr, int8_t *destAddr, int16_t destIncr, - uint32_t dmaSize, uint32_t xferSize, uint32_t initiator, int32_t priority, uint32_t flags, - uint32_t funcDesc); - int (*MCD_dmaStatus)(int channel); - int (*MCD_XferProgrQuery)(int channel, MCD_XferProg *progRep); - int (*MCD_killDma)(int channel); - int (*MCD_continDma)(int channel); - int (*MCD_pauseDma)(int channel); - int (*MCD_resumeDma)(int channel); - int (*MCD_csumQuery)(int channel, uint32_t *csum); - void *(*dma_malloc)(long amount); - int (*dma_free)(void *addr); + int32_t (*dma_set_initiator)(int32_t initiator); + uint32_t (*dma_get_initiator)(int32_t requestor); + void (*dma_free_initiator)(int32_t requestor); + int32_t (*dma_set_channel)(int32_t requestor, void (*handler)(void)); + int32_t (*dma_get_channel)(int32_t requestor); + void (*dma_free_channel)(int32_t requestor); + void (*dma_clear_channel)(int32_t channel); + int32_t (*MCD_startDma)(long channel, + int8_t *srcAddr, uint32_t srcIncr, int8_t *destAddr, uint32_t destIncr, + uint32_t dmaSize, uint32_t xferSize, uint32_t initiator, int32_t priority, + uint32_t flags, uint32_t funcDesc); + int32_t (*MCD_dmaStatus)(int32_t channel); + int32_t (*MCD_XferProgrQuery)(int32_t channel, MCD_XferProg *progRep); + int32_t (*MCD_killDma)(int32_t channel); + int32_t (*MCD_continDma)(int32_t channel); + int32_t (*MCD_pauseDma)(int32_t channel); + int32_t (*MCD_resumeDma)(int32_t channel); + int32_t (*MCD_csumQuery)(int32_t channel, uint32_t *csum); + void *(*dma_malloc)(uint32_t amount); + int32_t (*dma_free)(void *addr); }; struct xhdi_driver_interface diff --git a/net/am79c874.c b/net/am79c874.c new file mode 100644 index 0000000..252b636 --- /dev/null +++ b/net/am79c874.c @@ -0,0 +1,114 @@ +/* + * File: am79c874.c + * Purpose: Driver for the AMD AM79C874 10/100 Ethernet PHY + */ + +#include "net.h" +#include "fec.h" +#include "am79c874.h" + +#include "bas_printf.h" + +#if defined(MACHINE_FIREBEE) +#include "firebee.h" +#elif defined(MACHINE_M5484LITE) +#include "m5484l.h" +#else +#error "unknown machine" +#endif + +#define DBG_AM79 +#ifdef DBG_AM79 +#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0) +#else +#define dbg(format, arg...) do { ; } while (0) +#endif /* DBG_AM79 */ + +/********************************************************************/ +/* Initialize the AM79C874 PHY + * + * This function sets up the Auto-Negotiate Advertisement register + * within the PHY and then forces the PHY to auto-negotiate for + * it's settings. + * + * Params: + * fec_ch FEC channel + * phy_addr Address of the PHY. + * speed Desired speed (10BaseT or 100BaseTX) + * duplex Desired duplex (Full or Half) + * + * Return Value: + * 0 if MII commands fail + * 1 otherwise + */ +int am79c874_init(uint8_t fec_ch, uint8_t phy_addr, uint8_t speed, uint8_t duplex) +{ + int timeout; + uint16_t settings; + if (speed); /* to do */ + if (duplex); /* to do */ + + /* Initialize the MII interface */ + fec_mii_init(fec_ch, SYSCLK); + dbg("%s: PHY reset\r\n", __FUNCTION__); + + /* Reset the PHY */ + if (!fec_mii_write(fec_ch, phy_addr, MII_AM79C874_CR, MII_AM79C874_CR_RESET)) + return 0; + /* Wait for the PHY to reset */ + for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++) + { + fec_mii_read(fec_ch, phy_addr, MII_AM79C874_CR, &settings); + if (!(settings & MII_AM79C874_CR_RESET)) + break; + } + if (timeout >= FEC_MII_TIMEOUT) + return 0; + dbg("%s: PHY reset OK\r\n", __FUNCTION__); + dbg("%s: PHY Enable Auto-Negotiation\r\n", __FUNCTION__); + + /* Enable Auto-Negotiation */ + if (!fec_mii_write(fec_ch, phy_addr, MII_AM79C874_CR, MII_AM79C874_CR_AUTON | MII_AM79C874_CR_RST_NEG)) + return 0; + + dbg("%s:PHY Wait for auto-negotiation to complete\r\n", __FUNCTION__); + + /* Wait for auto-negotiation to complete */ + for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++) + { + settings = 0; + fec_mii_read(fec_ch, phy_addr, MII_AM79C874_SR, &settings); + if ((settings & AUTONEGLINK) == AUTONEGLINK) + break; + } + + if (timeout >= FEC_MII_TIMEOUT) + { + dbg("%s: PHY Set the default mode\r\n", __FUNCTION__); + + /* Set the default mode (Full duplex, 100 Mbps) */ + if (!fec_mii_write(fec_ch, phy_addr, MII_AM79C874_CR, MII_AM79C874_CR_100MB | MII_AM79C874_CR_DPLX)) + return 0; + } + +#ifdef DBG_AM79 + settings = 0; + + fec_mii_read(fec_ch, phy_addr, MII_AM79C874_DR, &settings); + + dbg("%s: PHY Mode:\r\n", __FUNCTION__); + if (settings & MII_AM79C874_DR_DATA_RATE) + dbg("%s: 100Mbps", __FUNCTION__); + else + dbg("%s: 10Mbps ", __FUNCTION__); + + if (settings & MII_AM79C874_DR_DPLX) + dbg("%s: Full-duplex\r\n", __FUNCTION__); + else + dbg("%s: Half-duplex\r\n", __FUNCTION__); + + dbg("%s:PHY auto-negociation complete\r\n", __FUNCTION__); +#endif /* DBG_AM79 */ + + return 1; +} diff --git a/net/fec.c b/net/fec.c index 8e16ef1..95bc92d 100644 --- a/net/fec.c +++ b/net/fec.c @@ -17,6 +17,7 @@ #include "bas_string.h" #include "bas_printf.h" #include "util.h" +#include "am79c874.h" #include #if defined(MACHINE_FIREBEE) @@ -544,19 +545,19 @@ void fec_rx_start(uint8_t ch, int8_t *rxbd) { uint32_t initiator; int channel; - int result; - - (void) result; /* to avoid compiler warning */ + int res; /* * Make the initiator assignment */ - result = dma_set_initiator(DMA_FEC_RX(ch)); + res = dma_set_initiator(DMA_FEC_RX(ch)); + dbg("%s: dma_set_initiator(DMA_FEC_RX(%d)): %d\r\n", __FUNCTION__, ch, res); /* * Grab the initiator number */ initiator = dma_get_initiator(DMA_FEC_RX(ch)); + dbg("%s: dma_get_initiator(DMA_FEC_RX(%d)) = %d\r\n", __FUNCTION__, ch, initiator); /* * Determine the DMA channel running the task for the @@ -564,6 +565,7 @@ void fec_rx_start(uint8_t ch, int8_t *rxbd) */ channel = dma_set_channel(DMA_FEC_RX(ch), (ch == 0) ? fec0_rx_frame : fec1_rx_frame); + dbg("%s: DMA channel for FEC%1d: %d\r\n", __FUNCTION__, ch, channel); /* * Start the Rx DMA task @@ -588,6 +590,7 @@ void fec_rx_start(uint8_t ch, int8_t *rxbd) | MCD_NO_CSUM | MCD_NO_BYTE_SWAP ); + dbg("%s: Rx DMA task for FEC%1d started\r\n", __FUNCTION__, ch); } /********************************************************************/ @@ -612,10 +615,13 @@ void fec_rx_continue(uint8_t ch) */ channel = dma_get_channel(DMA_FEC_RX(ch)); + dbg("%s: RX DMA channel for FEC%1d is %d\r\n", __FUNCTION__, ch, channel); + /* * Continue/restart the DMA task */ MCD_continDma(channel); + dbg("%s: RX dma on channel %d continued\r\n", __FUNCTION__, channel); } /********************************************************************/ @@ -850,13 +856,10 @@ void fec_tx_start(uint8_t ch, int8_t *txbd) void fec0_tx_frame(void); void fec1_tx_frame(void); - (void) result; /* to avoid compiler warning */ - /* FIXME: code assumes that there are always free initiator slots */ - /* * Make the initiator assignment */ - result = dma_set_initiator(DMA_FEC_TX(ch)); + (void) dma_set_initiator(DMA_FEC_TX(ch)); /* * Grab the initiator number @@ -1327,7 +1330,11 @@ void fec_eth_setup(uint8_t ch, uint8_t trcvr, uint8_t speed, uint8_t duplex, con /* * Initialize the MII interface */ +#if defined(MACHINE_FIREBEE) + am79c874_init(0, 0, speed, duplex); +#else fec_mii_init(ch, SYSCLK); +#endif /* MACHINE_FIREBEE */ } /* diff --git a/net/fecbd.c b/net/fecbd.c index b0d9206..3e0e598 100644 --- a/net/fecbd.c +++ b/net/fecbd.c @@ -62,89 +62,95 @@ static int iRxbd; */ void fecbd_init(uint8_t ch) { - NBUF *nbuf; - int i; - - /* - * Align Buffer Descriptors to 4-byte boundary - */ - RxBD = (FECBD *)(((int) unaligned_bds + 3) & 0xFFFFFFFC); - TxBD = (FECBD *)((int) RxBD + (sizeof(FECBD) * 2 * NRXBD)); + NBUF *nbuf; + int i; - /* - * Initialize the Rx Buffer Descriptor ring - */ - for (i = 0; i < NRXBD; ++i) - { - /* Grab a network buffer from the free list */ - nbuf = nbuf_alloc(); + dbg("%s:\r\n", __FUNCTION__); + + /* + * Align Buffer Descriptors to 4-byte boundary + */ + RxBD = (FECBD *)(((int) unaligned_bds + 3) & 0xFFFFFFFC); + TxBD = (FECBD *)((int) RxBD + (sizeof(FECBD) * 2 * NRXBD)); + + dbg("%s: initialise RX buffer descriptor ring\r\n", __FUNCTION__); + + /* + * Initialize the Rx Buffer Descriptor ring + */ + for (i = 0; i < NRXBD; ++i) + { + /* Grab a network buffer from the free list */ + nbuf = nbuf_alloc(); if (nbuf == NULL) { dbg("%s: could not allocate network buffer\r\n", __FUNCTION__); return; } - - /* Initialize the BD */ - RxBD(ch,i).status = RX_BD_E | RX_BD_INTERRUPT; - RxBD(ch,i).length = RX_BUF_SZ; - RxBD(ch,i).data = nbuf->data; - /* Add the network buffer to the Rx queue */ - nbuf_add(NBUF_RX_RING, nbuf); - } + /* Initialize the BD */ + RxBD(ch,i).status = RX_BD_E | RX_BD_INTERRUPT; + RxBD(ch,i).length = RX_BUF_SZ; + RxBD(ch,i).data = nbuf->data; - /* - * Set the WRAP bit on the last one - */ - RxBD(ch,i-1).status |= RX_BD_W; + /* Add the network buffer to the Rx queue */ + nbuf_add(NBUF_RX_RING, nbuf); + } - /* - * Initialize the Tx Buffer Descriptor ring - */ - for (i = 0; i < NTXBD; ++i) - { - TxBD(ch, i).status = TX_BD_INTERRUPT; - TxBD(ch, i).length = 0; - TxBD(ch, i).data = NULL; - } + /* + * Set the WRAP bit on the last one + */ + RxBD(ch, i - 1).status |= RX_BD_W; - /* - * Set the WRAP bit on the last one - */ - TxBD(ch,i-1).status |= TX_BD_W; + dbg("%s: initialise TX buffer descriptor ring\r\n", __FUNCTION__); - /* - * Initialize the buffer descriptor indexes - */ - iTxbd_new = iTxbd_old = iRxbd = 0; + /* + * Initialize the Tx Buffer Descriptor ring + */ + for (i = 0; i < NTXBD; ++i) + { + TxBD(ch, i).status = TX_BD_INTERRUPT; + TxBD(ch, i).length = 0; + TxBD(ch, i).data = NULL; + } + + /* + * Set the WRAP bit on the last one + */ + TxBD(ch, i - 1).status |= TX_BD_W; + + /* + * Initialize the buffer descriptor indexes + */ + iTxbd_new = iTxbd_old = iRxbd = 0; } void fecbd_dump(uint8_t ch) { - #ifdef DEBUG_PRINT - int i; +#ifdef DBG_FECBD + int i; - printf("\n------------ FEC%d BDs -----------\n",ch); - printf("RxBD Ring\n"); - for (i = 0; i < NRXBD; i++) - { - printf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n", - i, &RxBD(ch, i), - RxBD(ch, i).status, - RxBD(ch, i).length, - RxBD(ch, i).data); - } - printf("TxBD Ring\n"); - for (i = 0; i < NTXBD; i++) - { - printf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n", - i, &TxBD(ch, i), - TxBD(ch, i).status, - TxBD(ch, i).length, - TxBD(ch, i).data); - } - printf("--------------------------------\n\n"); - #endif + xprintf("\n------------ FEC%d BDs -----------\n",ch); + xprintf("RxBD Ring\n"); + for (i = 0; i < NRXBD; i++) + { + xprintf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n", + i, &RxBD(ch, i), + RxBD(ch, i).status, + RxBD(ch, i).length, + RxBD(ch, i).data); + } + xprintf("TxBD Ring\n"); + for (i = 0; i < NTXBD; i++) + { + xprintf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n", + i, &TxBD(ch, i), + TxBD(ch, i).status, + TxBD(ch, i).length, + TxBD(ch, i).data); + } + xprintf("--------------------------------\n\n"); +#endif /* DBG_FECBD */ } /* @@ -159,28 +165,28 @@ void fecbd_dump(uint8_t ch) */ uint32_t fecbd_get_start(uint8_t ch, uint8_t direction) { - switch (direction) - { - case Rx: - return (uint32_t)((int)RxBD + (ch * sizeof(FECBD) * NRXBD)); - case Tx: - default: - return (uint32_t)((int)TxBD + (ch * sizeof(FECBD) * NTXBD)); - } + switch (direction) + { + case Rx: + return (uint32_t)((int)RxBD + (ch * sizeof(FECBD) * NRXBD)); + case Tx: + default: + return (uint32_t)((int)TxBD + (ch * sizeof(FECBD) * NTXBD)); + } } FECBD *fecbd_rx_alloc(uint8_t ch) { - int i = iRxbd; + int i = iRxbd; - /* Check to see if the ring of BDs is full */ - if (RxBD(ch, i).status & RX_BD_E) - return NULL; + /* Check to see if the ring of BDs is full */ + if (RxBD(ch, i).status & RX_BD_E) + return NULL; - /* Increment the circular index */ - iRxbd = (uint8_t)((iRxbd + 1) % NRXBD); + /* Increment the circular index */ + iRxbd = (uint8_t)((iRxbd + 1) % NRXBD); - return &RxBD(ch, i); + return &RxBD(ch, i); } /* @@ -195,16 +201,16 @@ FECBD *fecbd_rx_alloc(uint8_t ch) */ FECBD *fecbd_tx_alloc(uint8_t ch) { - int i = iTxbd_new; + int i = iTxbd_new; - /* Check to see if the ring of BDs is full */ - if (TxBD(ch, i).status & TX_BD_R) - return NULL; + /* Check to see if the ring of BDs is full */ + if (TxBD(ch, i).status & TX_BD_R) + return NULL; - /* Increment the circular index */ - iTxbd_new = (uint8_t)((iTxbd_new + 1) % NTXBD); + /* Increment the circular index */ + iTxbd_new = (uint8_t)((iTxbd_new + 1) % NTXBD); - return &TxBD(ch, i); + return &TxBD(ch, i); } /* @@ -220,14 +226,14 @@ FECBD *fecbd_tx_alloc(uint8_t ch) */ FECBD *fecbd_tx_free(uint8_t ch) { - int i = iTxbd_old; + int i = iTxbd_old; - /* Check to see if the ring of BDs is empty */ - if ((TxBD(ch, i).data == NULL) || (TxBD(ch, i).status & TX_BD_R)) - return NULL; + /* Check to see if the ring of BDs is empty */ + if ((TxBD(ch, i).data == NULL) || (TxBD(ch, i).status & TX_BD_R)) + return NULL; - /* Increment the circular index */ - iTxbd_old = (uint8_t)((iTxbd_old + 1) % NTXBD); + /* Increment the circular index */ + iTxbd_old = (uint8_t)((iTxbd_old + 1) % NTXBD); - return &TxBD(ch, i); + return &TxBD(ch, i); } diff --git a/pci/pci.c b/pci/pci.c index fc93095..4a75b4c 100644 --- a/pci/pci.c +++ b/pci/pci.c @@ -892,9 +892,9 @@ void init_xlbus_arbiter(void) MCF_XLB_XARB_PRIEN = MCF_XLB_XARB_PRIEN_M0 | /* activate programmed priority for Coldfire core */ MCF_XLB_XARB_PRIEN_M2 | /* activate programmed priority for Multichannel DMA */ MCF_XLB_XARB_PRIEN_M3; /* activate programmed priority for PCI target interface */ - MCF_XLB_XARB_PRI = MCF_XLB_XARB_PRI_M0P(7) | /* Coldfire core gets lowest */ + MCF_XLB_XARB_PRI = MCF_XLB_XARB_PRI_M0P(3) | /* Coldfire core gets lowest */ MCF_XLB_XARB_PRI_M2P(5) | /* Multichannel DMA mid priority */ - MCF_XLB_XARB_PRI_M3P(3); /* PCI target interface is highest priority */ + MCF_XLB_XARB_PRI_M3P(7); /* PCI target interface is highest priority */ } void init_pci(void) diff --git a/sys/BaS.c b/sys/BaS.c index f0d9fe1..6a1c8a1 100644 --- a/sys/BaS.c +++ b/sys/BaS.c @@ -263,6 +263,7 @@ void network_init(void) vector = 103; isr_init(); /* need to call that explicitely, otherwise isr table might be full */ + if (!isr_register_handler(ISR_DBUG_ISR, vector, handler, NULL, (void *) &nif1)) { dbg("%s: unable to register handler for vector %d\r\n", __FUNCTION__, vector); @@ -281,7 +282,6 @@ void network_init(void) return; } -#ifdef _NOT_USED_ nif_init(&nif1); nif1.mtu = ETH_MTU; nif1.send = fec0_send; @@ -295,7 +295,6 @@ void network_init(void) ip_init(&ip_info, myip, gateway, netmask); nif_bind_protocol(&nif1, ETH_FRM_IP, ip_handler, (void *) &ip_info); -#endif dma_irq_enable(6, 6); //set_ipl(0); diff --git a/sys/driver_mem.c b/sys/driver_mem.c index 8b06558..faabc3b 100644 --- a/sys/driver_mem.c +++ b/sys/driver_mem.c @@ -32,7 +32,6 @@ #define dbg(fmt, args...) #endif -extern void *info_fvdi; extern long offscren_reserved(void); extern uint8_t driver_mem_buffer[DRIVER_MEM_BUFFER_SIZE]; /* defined in linker control file */ @@ -231,7 +230,7 @@ static void freeit(MD *m, MPB *mp) } } -int driver_mem_free(void *addr) +int32_t driver_mem_free(void *addr) { int level; MD *p, **q; @@ -262,7 +261,7 @@ int driver_mem_free(void *addr) return(0); } -void *driver_mem_alloc(long amount) +void *driver_mem_alloc(uint32_t amount) { void *ret = NULL; int level; diff --git a/sys/exceptions.S b/sys/exceptions.S index 8c3fdbf..3a206d9 100644 --- a/sys/exceptions.S +++ b/sys/exceptions.S @@ -295,24 +295,27 @@ init_vec_loop: lea handler_psc3(pc),a1 // PSC3 interrupt source = 32 move.l a1,(INT_SOURCE_PSC3 + 64) * 4(a0) + // timer vectors (triggers when vbashi gets changed, used for video page copy) lea handler_gpt0(pc),a1 // GPT0 interrupt source = 62 move.l a1,(INT_SOURCE_GPT0 + 64) * 4(a0) #endif /* MACHINE_FIREBEE */ - // install isr handlers for the three GPT timers, - // the FEC interrupts and the DMA task interrupts - // (used by network driver in BaS and MiNT) - lea _lowlevel_isr_handler,a1 +// install lowlevel_isr_handler for the three GPT timers + lea _lowlevel_isr_handler(pc),a1 move.l a1,(INT_SOURCE_GPT1 + 64) * 4(a0) move.l a1,(INT_SOURCE_GPT2 + 64) * 4(a0) move.l a1,(INT_SOURCE_GPT3 + 64) * 4(a0) + +// install lowlevel_isr_handler for the FEC0 interrupt move.l a1,(INT_SOURCE_FEC0 + 64) * 4(a0) #ifndef MACHINE_FIREBEE - // second FEC not wired on the FireBee +// FEC1 not wired on the FireBee move.l a1,(INT_SOURCE_FEC1 + 64) * 4(a0) #endif + +// install lowlevel_isr_handler for DMA interrupts move.l a1,(INT_SOURCE_DMA + 64) * 4(a0) move.l (sp)+,a2 // Restore registers @@ -990,24 +993,16 @@ video_chg_end: .extern _isr_execute_handler _lowlevel_isr_handler: - move.w #0x2700,sr - link a6,#-4*4 - movem.l d0-d1/a0-a1,(sp) + move.w #0x2700,sr // disable interrupts + link a6,#-4*4 // make room for + movem.l d0-d1/a0-a1,(sp) // gcc scratch registers and save them - move.w 4(a6),d0 - lsr.l #2,d0 - andi.l #0x0000ff,d0 - move.l d0,-(sp) - jsr _isr_execute_handler - lea 4(sp),sp - cmp.l #1,d0 - //beq handled // this is probably not a too bright idea for hw interrupts not known to TOS - bra handled -nothandled: - movem.l (sp),d0-d1/a0-a1 - unlk a6 - jmp std_exc_vec -handled: - movem.l (sp),d0-d1/a0-a1 - unlk a6 + move.w 4(a6),d0 // fetch vector number from stack + lsr.l #2,d0 // move it in place + andi.l #0x000000ff,d0 // mask it out + move.l d0,-(sp) // push it + jsr _isr_execute_handler // call the C handler + lea 4(sp),sp // adjust stack + movem.l (sp),d0-d1/a0-a1 // restore registers + unlk a6 // cleanup stack rte