implemented PHY, but still only occasionly transmitted packets. Obviously, there's a bug somewhere ;)

This commit is contained in:
Markus Fröschle
2014-01-02 21:33:27 +00:00
parent 4017a336a9
commit 3034ede3a6
14 changed files with 396 additions and 211 deletions

View File

@@ -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 # can be either "Y" or "N" (without quotes). "Y" for using the m68k-elf-, "N" for using the m68k-atari-mint
# toolchain # toolchain
COMPILE_ELF=Y COMPILE_ELF=N
ifeq (Y,$(COMPILE_ELF)) ifeq (Y,$(COMPILE_ELF))
TCPREFIX=m68k-elf- TCPREFIX=m68k-elf-
@@ -93,6 +93,7 @@ CSRCS= \
nbuf.c \ nbuf.c \
queue.c \ queue.c \
net_timer.c \ net_timer.c \
am79c874.c \
nif.c \ nif.c \
fecbd.c \ fecbd.c \
fec.c \ fec.c \

View File

@@ -59,6 +59,7 @@ SECTIONS
OBJDIR/nif.o(.text) OBJDIR/nif.o(.text)
OBJDIR/fecbd.o(.text) OBJDIR/fecbd.o(.text)
OBJDIR/fec.o(.text) OBJDIR/fec.o(.text)
OBJDIR/am79c874.o(.text)
OBJDIR/ip.o(.text) OBJDIR/ip.o(.text)
OBJDIR/udp.o(text) OBJDIR/udp.o(text)
OBJDIR/bootp.o(text) OBJDIR/bootp.o(text)

View File

@@ -131,40 +131,34 @@ int dma_set_initiator(int initiator)
break; break;
case DMA_FEC0_RX: case DMA_FEC0_RX:
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC16(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC16(3)) | MCF_DMA_IMCR_IMC16_FEC0RX;
| MCF_DMA_IMCR_IMC16_FEC0RX;
used_reqs[16] = DMA_FEC0_RX; used_reqs[16] = DMA_FEC0_RX;
break; break;
case DMA_FEC0_TX: case DMA_FEC0_TX:
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC17(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC17(3)) | MCF_DMA_IMCR_IMC17_FEC0TX;
| MCF_DMA_IMCR_IMC17_FEC0TX;
used_reqs[17] = DMA_FEC0_TX; used_reqs[17] = DMA_FEC0_TX;
break; break;
case DMA_FEC1_RX: case DMA_FEC1_RX:
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC20(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC20(3)) | MCF_DMA_IMCR_IMC20_FEC1RX;
| MCF_DMA_IMCR_IMC20_FEC1RX;
used_reqs[20] = DMA_FEC1_RX; used_reqs[20] = DMA_FEC1_RX;
break; break;
case DMA_FEC1_TX: case DMA_FEC1_TX:
if (used_reqs[21] == 0) if (used_reqs[21] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC21(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC21(3)) | MCF_DMA_IMCR_IMC21_FEC1TX;
| MCF_DMA_IMCR_IMC21_FEC1TX;
used_reqs[21] = DMA_FEC1_TX; used_reqs[21] = DMA_FEC1_TX;
} }
else if (used_reqs[25] == 0) else if (used_reqs[25] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC25(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC25(3)) | MCF_DMA_IMCR_IMC25_FEC1TX;
| MCF_DMA_IMCR_IMC25_FEC1TX;
used_reqs[25] = DMA_FEC1_TX; used_reqs[25] = DMA_FEC1_TX;
} }
else if (used_reqs[31] == 0) else if (used_reqs[31] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC31(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC31(3)) | MCF_DMA_IMCR_IMC31_FEC1TX;
| MCF_DMA_IMCR_IMC31_FEC1TX;
used_reqs[31] = DMA_FEC1_TX; used_reqs[31] = DMA_FEC1_TX;
} }
else /* No empty slots */ else /* No empty slots */
@@ -178,14 +172,12 @@ int dma_set_initiator(int initiator)
case DMA_DREQ1: case DMA_DREQ1:
if (used_reqs[29] == 0) if (used_reqs[29] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC29(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC29(3)) | MCF_DMA_IMCR_IMC29_DREQ1;
| MCF_DMA_IMCR_IMC29_DREQ1;
used_reqs[29] = DMA_DREQ1; used_reqs[29] = DMA_DREQ1;
} }
else if (used_reqs[21] == 0) else if (used_reqs[21] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC21(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC21(3)) | MCF_DMA_IMCR_IMC21_DREQ1;
| MCF_DMA_IMCR_IMC21_DREQ1;
used_reqs[21] = DMA_DREQ1; used_reqs[21] = DMA_DREQ1;
} }
else /* No empty slots */ else /* No empty slots */
@@ -199,8 +191,7 @@ int dma_set_initiator(int initiator)
case DMA_CTM0: case DMA_CTM0:
if (used_reqs[24] == 0) if (used_reqs[24] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC24(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC24(3)) | MCF_DMA_IMCR_IMC24_CTM0;
| MCF_DMA_IMCR_IMC24_CTM0;
used_reqs[24] = DMA_CTM0; used_reqs[24] = DMA_CTM0;
} }
else /* No empty slots */ else /* No empty slots */
@@ -214,8 +205,7 @@ int dma_set_initiator(int initiator)
case DMA_CTM1: case DMA_CTM1:
if (used_reqs[25] == 0) if (used_reqs[25] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC25(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC25(3)) | MCF_DMA_IMCR_IMC25_CTM1;
| MCF_DMA_IMCR_IMC25_CTM1;
used_reqs[25] = DMA_CTM1; used_reqs[25] = DMA_CTM1;
} }
else /* No empty slots */ else /* No empty slots */
@@ -229,8 +219,7 @@ int dma_set_initiator(int initiator)
case DMA_CTM2: case DMA_CTM2:
if (used_reqs[26] == 0) if (used_reqs[26] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC26(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC26(3)) | MCF_DMA_IMCR_IMC26_CTM2;
| MCF_DMA_IMCR_IMC26_CTM2;
used_reqs[26] = DMA_CTM2; used_reqs[26] = DMA_CTM2;
} }
else /* No empty slots */ else /* No empty slots */
@@ -244,8 +233,7 @@ int dma_set_initiator(int initiator)
case DMA_CTM3: case DMA_CTM3:
if (used_reqs[27] == 0) if (used_reqs[27] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC27(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC27(3)) | MCF_DMA_IMCR_IMC27_CTM3;
| MCF_DMA_IMCR_IMC27_CTM3;
used_reqs[27] = DMA_CTM3; used_reqs[27] = DMA_CTM3;
} }
else /* No empty slots */ else /* No empty slots */
@@ -259,8 +247,7 @@ int dma_set_initiator(int initiator)
case DMA_CTM4: case DMA_CTM4:
if (used_reqs[28] == 0) if (used_reqs[28] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC28(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC28(3)) | MCF_DMA_IMCR_IMC28_CTM4;
| MCF_DMA_IMCR_IMC28_CTM4;
used_reqs[28] = DMA_CTM4; used_reqs[28] = DMA_CTM4;
} }
else /* No empty slots */ else /* No empty slots */
@@ -274,8 +261,7 @@ int dma_set_initiator(int initiator)
case DMA_CTM5: case DMA_CTM5:
if (used_reqs[29] == 0) if (used_reqs[29] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC29(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC29(3)) | MCF_DMA_IMCR_IMC29_CTM5;
| MCF_DMA_IMCR_IMC29_CTM5;
used_reqs[29] = DMA_CTM5; used_reqs[29] = DMA_CTM5;
} }
else /* No empty slots */ else /* No empty slots */
@@ -289,8 +275,7 @@ int dma_set_initiator(int initiator)
case DMA_CTM6: case DMA_CTM6:
if (used_reqs[30] == 0) if (used_reqs[30] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC30(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC30(3)) | MCF_DMA_IMCR_IMC30_CTM6;
| MCF_DMA_IMCR_IMC30_CTM6;
used_reqs[30] = DMA_CTM6; used_reqs[30] = DMA_CTM6;
} }
else /* No empty slots */ else /* No empty slots */
@@ -304,8 +289,7 @@ int dma_set_initiator(int initiator)
case DMA_CTM7: case DMA_CTM7:
if (used_reqs[31] == 0) if (used_reqs[31] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC31(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC31(3)) | MCF_DMA_IMCR_IMC31_CTM7;
| MCF_DMA_IMCR_IMC31_CTM7;
used_reqs[31] = DMA_CTM7; used_reqs[31] = DMA_CTM7;
} }
else /* No empty slots */ else /* No empty slots */
@@ -319,8 +303,7 @@ int dma_set_initiator(int initiator)
case DMA_USBEP4: case DMA_USBEP4:
if (used_reqs[26] == 0) if (used_reqs[26] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC26(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC26(3)) | MCF_DMA_IMCR_IMC26_USBEP4;
| MCF_DMA_IMCR_IMC26_USBEP4;
used_reqs[26] = DMA_USBEP4; used_reqs[26] = DMA_USBEP4;
} }
else /* No empty slots */ else /* No empty slots */
@@ -334,8 +317,7 @@ int dma_set_initiator(int initiator)
case DMA_USBEP5: case DMA_USBEP5:
if (used_reqs[27] == 0) if (used_reqs[27] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC27(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC27(3)) | MCF_DMA_IMCR_IMC27_USBEP5;
| MCF_DMA_IMCR_IMC27_USBEP5;
used_reqs[27] = DMA_USBEP5; used_reqs[27] = DMA_USBEP5;
} }
else /* No empty slots */ else /* No empty slots */
@@ -349,8 +331,7 @@ int dma_set_initiator(int initiator)
case DMA_USBEP6: case DMA_USBEP6:
if (used_reqs[28] == 0) if (used_reqs[28] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC28(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC28(3)) | MCF_DMA_IMCR_IMC28_USBEP6;
| MCF_DMA_IMCR_IMC28_USBEP6;
used_reqs[28] = DMA_USBEP6; used_reqs[28] = DMA_USBEP6;
} }
else /* No empty slots */ else /* No empty slots */
@@ -359,8 +340,7 @@ int dma_set_initiator(int initiator)
case DMA_PSC2_RX: case DMA_PSC2_RX:
if (used_reqs[28] == 0) if (used_reqs[28] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC28(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC28(3)) | MCF_DMA_IMCR_IMC28_PSC2RX;
| MCF_DMA_IMCR_IMC28_PSC2RX;
used_reqs[28] = DMA_PSC2_RX; } used_reqs[28] = DMA_PSC2_RX; }
else /* No empty slots */ else /* No empty slots */
{ {
@@ -373,8 +353,7 @@ int dma_set_initiator(int initiator)
case DMA_PSC2_TX: case DMA_PSC2_TX:
if (used_reqs[29] == 0) if (used_reqs[29] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC29(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC29(3)) | MCF_DMA_IMCR_IMC29_PSC2TX;
| MCF_DMA_IMCR_IMC29_PSC2TX;
used_reqs[29] = DMA_PSC2_TX; used_reqs[29] = DMA_PSC2_TX;
} }
else /* No empty slots */ else /* No empty slots */
@@ -388,8 +367,7 @@ int dma_set_initiator(int initiator)
case DMA_PSC3_RX: case DMA_PSC3_RX:
if (used_reqs[30] == 0) if (used_reqs[30] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC30(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC30(3)) | MCF_DMA_IMCR_IMC30_PSC3RX;
| MCF_DMA_IMCR_IMC30_PSC3RX;
used_reqs[30] = DMA_PSC3_RX; used_reqs[30] = DMA_PSC3_RX;
} }
else /* No empty slots */ else /* No empty slots */
@@ -403,8 +381,7 @@ int dma_set_initiator(int initiator)
case DMA_PSC3_TX: case DMA_PSC3_TX:
if (used_reqs[31] == 0) if (used_reqs[31] == 0)
{ {
MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC31(3)) MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_IMC31(3)) | MCF_DMA_IMCR_IMC31_PSC3TX;
| MCF_DMA_IMCR_IMC31_PSC3TX;
used_reqs[31] = DMA_PSC3_TX; used_reqs[31] = DMA_PSC3_TX;
} }
else /* No empty slots */ else /* No empty slots */
@@ -565,12 +542,10 @@ void dma_free_channel(int requestor)
int dma_interrupt_handler(void *arg1, void *arg2) int dma_interrupt_handler(void *arg1, void *arg2)
{ {
uint32_t i, interrupts; uint32_t i, interrupts;
uint32_t ipl;
(void)arg1; dbg("%s: arg1 = %p, arg2 = %p\r\n", __FUNCTION__, arg1, arg2);
(void)arg2;
ipl = set_ipl(7); (void) set_ipl(7);
/* /*
* Determine which interrupt(s) triggered by AND'ing the * Determine which interrupt(s) triggered by AND'ing the
@@ -591,11 +566,12 @@ int dma_interrupt_handler(void *arg1, void *arg2)
{ {
/* If there is a handler, call it */ /* If there is a handler, call it */
if (dma_channel[i].handler != NULL) 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(); dma_channel[i].handler();
} }
} }
}
set_ipl(ipl);
return 1; return 1;
} }

85
include/am79c874.h Normal file
View File

@@ -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_ */

View File

@@ -1,6 +1,5 @@
/* /*
* spidma.h * spidma.h *
*
* This file is part of BaS_gcc. * This file is part of BaS_gcc.
* *
* BaS_gcc is free software: you can redistribute it and/or modify * BaS_gcc is free software: you can redistribute it and/or modify

View File

@@ -1,13 +1,15 @@
#ifndef _DRIVER_MEM_H_ #ifndef _DRIVER_MEM_H_
#define _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 * the driver_mem module provides a block of _uncached_ memory for USB and other drivers as
* well as some memory handling functions for it * well as some memory handling functions for it
*/ */
extern int driver_mem_init(void); extern int driver_mem_init(void);
extern void *driver_mem_alloc(long amount); extern void *driver_mem_alloc(uint32_t amount);
extern int driver_mem_free(void *addr); extern int32_t driver_mem_free(void *addr);
extern void driver_mem_release(void); extern void driver_mem_release(void);
#endif /* _DRIVER_MEM_H_ */ #endif /* _DRIVER_MEM_H_ */

View File

@@ -50,25 +50,26 @@ struct dma_driver_interface
{ {
int32_t version; int32_t version;
int32_t magic; int32_t magic;
int32_t (*dma_set_initiator)(int initiator); int32_t (*dma_set_initiator)(int32_t initiator);
uint32_t (*dma_get_initiator)(int requestor); uint32_t (*dma_get_initiator)(int32_t requestor);
void (*dma_free_initiator)(int requestor); void (*dma_free_initiator)(int32_t requestor);
int32_t (*dma_set_channel)(int requestor, void (*handler)(void)); int32_t (*dma_set_channel)(int32_t requestor, void (*handler)(void));
int (*dma_get_channel)(int requestor); int32_t (*dma_get_channel)(int32_t requestor);
void (*dma_free_channel)(int requestor); void (*dma_free_channel)(int32_t requestor);
void (*dma_clear_channel)(int channel); void (*dma_clear_channel)(int32_t channel);
int (*MCD_startDma)(int channel, int8_t *srcAddr, int16_t srcIncr, int8_t *destAddr, int16_t destIncr, int32_t (*MCD_startDma)(long channel,
uint32_t dmaSize, uint32_t xferSize, uint32_t initiator, int32_t priority, uint32_t flags, int8_t *srcAddr, uint32_t srcIncr, int8_t *destAddr, uint32_t destIncr,
uint32_t funcDesc); uint32_t dmaSize, uint32_t xferSize, uint32_t initiator, int32_t priority,
int (*MCD_dmaStatus)(int channel); uint32_t flags, uint32_t funcDesc);
int (*MCD_XferProgrQuery)(int channel, MCD_XferProg *progRep); int32_t (*MCD_dmaStatus)(int32_t channel);
int (*MCD_killDma)(int channel); int32_t (*MCD_XferProgrQuery)(int32_t channel, MCD_XferProg *progRep);
int (*MCD_continDma)(int channel); int32_t (*MCD_killDma)(int32_t channel);
int (*MCD_pauseDma)(int channel); int32_t (*MCD_continDma)(int32_t channel);
int (*MCD_resumeDma)(int channel); int32_t (*MCD_pauseDma)(int32_t channel);
int (*MCD_csumQuery)(int channel, uint32_t *csum); int32_t (*MCD_resumeDma)(int32_t channel);
void *(*dma_malloc)(long amount); int32_t (*MCD_csumQuery)(int32_t channel, uint32_t *csum);
int (*dma_free)(void *addr); void *(*dma_malloc)(uint32_t amount);
int32_t (*dma_free)(void *addr);
}; };
struct xhdi_driver_interface struct xhdi_driver_interface

114
net/am79c874.c Normal file
View File

@@ -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;
}

View File

@@ -17,6 +17,7 @@
#include "bas_string.h" #include "bas_string.h"
#include "bas_printf.h" #include "bas_printf.h"
#include "util.h" #include "util.h"
#include "am79c874.h"
#include <stdbool.h> #include <stdbool.h>
#if defined(MACHINE_FIREBEE) #if defined(MACHINE_FIREBEE)
@@ -544,19 +545,19 @@ void fec_rx_start(uint8_t ch, int8_t *rxbd)
{ {
uint32_t initiator; uint32_t initiator;
int channel; int channel;
int result; int res;
(void) result; /* to avoid compiler warning */
/* /*
* Make the initiator assignment * 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 * Grab the initiator number
*/ */
initiator = dma_get_initiator(DMA_FEC_RX(ch)); 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 * 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), channel = dma_set_channel(DMA_FEC_RX(ch),
(ch == 0) ? fec0_rx_frame : fec1_rx_frame); (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 * Start the Rx DMA task
@@ -588,6 +590,7 @@ void fec_rx_start(uint8_t ch, int8_t *rxbd)
| MCD_NO_CSUM | MCD_NO_CSUM
| MCD_NO_BYTE_SWAP | 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)); 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 * Continue/restart the DMA task
*/ */
MCD_continDma(channel); 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 fec0_tx_frame(void);
void fec1_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 * Make the initiator assignment
*/ */
result = dma_set_initiator(DMA_FEC_TX(ch)); (void) dma_set_initiator(DMA_FEC_TX(ch));
/* /*
* Grab the initiator number * 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 * Initialize the MII interface
*/ */
#if defined(MACHINE_FIREBEE)
am79c874_init(0, 0, speed, duplex);
#else
fec_mii_init(ch, SYSCLK); fec_mii_init(ch, SYSCLK);
#endif /* MACHINE_FIREBEE */
} }
/* /*

View File

@@ -65,12 +65,16 @@ void fecbd_init(uint8_t ch)
NBUF *nbuf; NBUF *nbuf;
int i; int i;
dbg("%s:\r\n", __FUNCTION__);
/* /*
* Align Buffer Descriptors to 4-byte boundary * Align Buffer Descriptors to 4-byte boundary
*/ */
RxBD = (FECBD *)(((int) unaligned_bds + 3) & 0xFFFFFFFC); RxBD = (FECBD *)(((int) unaligned_bds + 3) & 0xFFFFFFFC);
TxBD = (FECBD *)((int) RxBD + (sizeof(FECBD) * 2 * NRXBD)); TxBD = (FECBD *)((int) RxBD + (sizeof(FECBD) * 2 * NRXBD));
dbg("%s: initialise RX buffer descriptor ring\r\n", __FUNCTION__);
/* /*
* Initialize the Rx Buffer Descriptor ring * Initialize the Rx Buffer Descriptor ring
*/ */
@@ -96,7 +100,9 @@ void fecbd_init(uint8_t ch)
/* /*
* Set the WRAP bit on the last one * Set the WRAP bit on the last one
*/ */
RxBD(ch,i-1).status |= RX_BD_W; RxBD(ch, i - 1).status |= RX_BD_W;
dbg("%s: initialise TX buffer descriptor ring\r\n", __FUNCTION__);
/* /*
* Initialize the Tx Buffer Descriptor ring * Initialize the Tx Buffer Descriptor ring
@@ -111,7 +117,7 @@ void fecbd_init(uint8_t ch)
/* /*
* Set the WRAP bit on the last one * Set the WRAP bit on the last one
*/ */
TxBD(ch,i-1).status |= TX_BD_W; TxBD(ch, i - 1).status |= TX_BD_W;
/* /*
* Initialize the buffer descriptor indexes * Initialize the buffer descriptor indexes
@@ -121,30 +127,30 @@ void fecbd_init(uint8_t ch)
void fecbd_dump(uint8_t ch) void fecbd_dump(uint8_t ch)
{ {
#ifdef DEBUG_PRINT #ifdef DBG_FECBD
int i; int i;
printf("\n------------ FEC%d BDs -----------\n",ch); xprintf("\n------------ FEC%d BDs -----------\n",ch);
printf("RxBD Ring\n"); xprintf("RxBD Ring\n");
for (i = 0; i < NRXBD; i++) for (i = 0; i < NRXBD; i++)
{ {
printf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n", xprintf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n",
i, &RxBD(ch, i), i, &RxBD(ch, i),
RxBD(ch, i).status, RxBD(ch, i).status,
RxBD(ch, i).length, RxBD(ch, i).length,
RxBD(ch, i).data); RxBD(ch, i).data);
} }
printf("TxBD Ring\n"); xprintf("TxBD Ring\n");
for (i = 0; i < NTXBD; i++) for (i = 0; i < NTXBD; i++)
{ {
printf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n", xprintf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n",
i, &TxBD(ch, i), i, &TxBD(ch, i),
TxBD(ch, i).status, TxBD(ch, i).status,
TxBD(ch, i).length, TxBD(ch, i).length,
TxBD(ch, i).data); TxBD(ch, i).data);
} }
printf("--------------------------------\n\n"); xprintf("--------------------------------\n\n");
#endif #endif /* DBG_FECBD */
} }
/* /*

View File

@@ -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 = 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_M2 | /* activate programmed priority for Multichannel DMA */
MCF_XLB_XARB_PRIEN_M3; /* activate programmed priority for PCI target interface */ 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_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) void init_pci(void)

View File

@@ -263,6 +263,7 @@ void network_init(void)
vector = 103; vector = 103;
isr_init(); /* need to call that explicitely, otherwise isr table might be full */ 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)) 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); dbg("%s: unable to register handler for vector %d\r\n", __FUNCTION__, vector);
@@ -281,7 +282,6 @@ void network_init(void)
return; return;
} }
#ifdef _NOT_USED_
nif_init(&nif1); nif_init(&nif1);
nif1.mtu = ETH_MTU; nif1.mtu = ETH_MTU;
nif1.send = fec0_send; nif1.send = fec0_send;
@@ -295,7 +295,6 @@ void network_init(void)
ip_init(&ip_info, myip, gateway, netmask); ip_init(&ip_info, myip, gateway, netmask);
nif_bind_protocol(&nif1, ETH_FRM_IP, ip_handler, (void *) &ip_info); nif_bind_protocol(&nif1, ETH_FRM_IP, ip_handler, (void *) &ip_info);
#endif
dma_irq_enable(6, 6); dma_irq_enable(6, 6);
//set_ipl(0); //set_ipl(0);

View File

@@ -32,7 +32,6 @@
#define dbg(fmt, args...) #define dbg(fmt, args...)
#endif #endif
extern void *info_fvdi;
extern long offscren_reserved(void); extern long offscren_reserved(void);
extern uint8_t driver_mem_buffer[DRIVER_MEM_BUFFER_SIZE]; /* defined in linker control file */ 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; int level;
MD *p, **q; MD *p, **q;
@@ -262,7 +261,7 @@ int driver_mem_free(void *addr)
return(0); return(0);
} }
void *driver_mem_alloc(long amount) void *driver_mem_alloc(uint32_t amount)
{ {
void *ret = NULL; void *ret = NULL;
int level; int level;

View File

@@ -295,24 +295,27 @@ init_vec_loop:
lea handler_psc3(pc),a1 lea handler_psc3(pc),a1
// PSC3 interrupt source = 32 // PSC3 interrupt source = 32
move.l a1,(INT_SOURCE_PSC3 + 64) * 4(a0) move.l a1,(INT_SOURCE_PSC3 + 64) * 4(a0)
// timer vectors (triggers when vbashi gets changed, used for video page copy) // timer vectors (triggers when vbashi gets changed, used for video page copy)
lea handler_gpt0(pc),a1 lea handler_gpt0(pc),a1
// GPT0 interrupt source = 62 // GPT0 interrupt source = 62
move.l a1,(INT_SOURCE_GPT0 + 64) * 4(a0) move.l a1,(INT_SOURCE_GPT0 + 64) * 4(a0)
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
// install isr handlers for the three GPT timers, // install lowlevel_isr_handler for the three GPT timers
// the FEC interrupts and the DMA task interrupts lea _lowlevel_isr_handler(pc),a1
// (used by network driver in BaS and MiNT)
lea _lowlevel_isr_handler,a1
move.l a1,(INT_SOURCE_GPT1 + 64) * 4(a0) move.l a1,(INT_SOURCE_GPT1 + 64) * 4(a0)
move.l a1,(INT_SOURCE_GPT2 + 64) * 4(a0) move.l a1,(INT_SOURCE_GPT2 + 64) * 4(a0)
move.l a1,(INT_SOURCE_GPT3 + 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) move.l a1,(INT_SOURCE_FEC0 + 64) * 4(a0)
#ifndef MACHINE_FIREBEE #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) move.l a1,(INT_SOURCE_FEC1 + 64) * 4(a0)
#endif #endif
// install lowlevel_isr_handler for DMA interrupts
move.l a1,(INT_SOURCE_DMA + 64) * 4(a0) move.l a1,(INT_SOURCE_DMA + 64) * 4(a0)
move.l (sp)+,a2 // Restore registers move.l (sp)+,a2 // Restore registers
@@ -990,24 +993,16 @@ video_chg_end:
.extern _isr_execute_handler .extern _isr_execute_handler
_lowlevel_isr_handler: _lowlevel_isr_handler:
move.w #0x2700,sr move.w #0x2700,sr // disable interrupts
link a6,#-4*4 link a6,#-4*4 // make room for
movem.l d0-d1/a0-a1,(sp) movem.l d0-d1/a0-a1,(sp) // gcc scratch registers and save them
move.w 4(a6),d0 move.w 4(a6),d0 // fetch vector number from stack
lsr.l #2,d0 lsr.l #2,d0 // move it in place
andi.l #0x0000ff,d0 andi.l #0x000000ff,d0 // mask it out
move.l d0,-(sp) move.l d0,-(sp) // push it
jsr _isr_execute_handler jsr _isr_execute_handler // call the C handler
lea 4(sp),sp lea 4(sp),sp // adjust stack
cmp.l #1,d0 movem.l (sp),d0-d1/a0-a1 // restore registers
//beq handled // this is probably not a too bright idea for hw interrupts not known to TOS unlk a6 // cleanup stack
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
rte rte