I need to use internal FEC with an external MAC device (SMSC LAN8740A).
My PHYs that do not have all the MII pins, for this reason I've chose MII-Lite configuration.
I've configured all registers as I think are good but unfortunately my FEC don't dialogue correctly with external MAC.
In attachment my hardware configuration, this is my software configuration:
static int drvOpen( NGifnet *netp)
{
FEC_regs *regs;
NGfecif_bd *RxTxBD;
int i, ictl;
/* ****************************************************************
* check stack configuration (must be divisible by 16)
**************************************************************** */
if( ((ngBufDataOffset + ngBufDataMax) & 15) != 0) return( NG_ENXIO);
ng_siu_init();
/* *****************************************************************************************************
* install PHY/MII functions
***************************************************************************************************** */
NG_ETHIF_DATA( netp, eif_phy_write) = phy_write;
NG_ETHIF_DATA( netp, eif_phy_read) = phy_read;
/* *****************************************************************************************************
* Initialize ptr for config access
***************************************************************************************************** */
regs = (FEC_regs *) (ngM68K_MBAR + FEC_OFFSET);
/* *****************************************************************************************************
* Ethernet Control Register * - reset device
***************************************************************************************************** */
regs->FEC_ECR = ECR_RESET;
/* *****************************************************************************************************
* Initialize Tx and Rx Descriptors
***************************************************************************************************** */
netp->if_devptr1 = (void *) (( ((NGuint) netp) + sizeof(NGfecifnet) + 15) & ~15);
RxTxBD = (NGfecif_bd *)netp->if_devptr1;
/* *****************************************************************************************************
* RxBDs
***************************************************************************************************** */
for( i=0; i<NG_FECIF_NUM_RXBDS; i++) {
/* allocate buffer for reception */
ngBufAlloc( ((NGfecifnet *) netp)->Bufi[i] );
((NGfecifnet *) netp)->Bufi[i]->buf_datap =
(NGubyte *)((NGfecifnet *) netp)->Bufi[i] + netp->if_dev1;
((NGfecifnet *) netp)->Bufi[i]->buf_datalen = 0;
/* prepare RxBD */
RxTxBD->RxBD[i].bd_addr = ((NGfecifnet *) netp)->Bufi[i]->buf_datap;
RxTxBD->RxBD[i].bd_length = 0;
RxTxBD->RxBD[i].bd_cstatus = BD_RX_E;
}
RxTxBD->RxBD[NG_FECIF_NUM_RXBDS-1].bd_cstatus |= BD_RX_W;
((NGfecifnet *) netp)->RxIdx = 0;
/* *****************************************************************************************************
* TxBDs
***************************************************************************************************** */
for( i=0; i<NG_FECIF_NUM_TXBDS; i++) {
/* prepare TxBD */
RxTxBD->TxBD[i].bd_cstatus = 0;
((NGfecifnet *) netp)->Bufo[i] = NULL;
}
RxTxBD->TxBD[NG_FECIF_NUM_TXBDS-1].bd_cstatus |= BD_TX_W;
((NGfecifnet *) netp)->TxCount = 0;
((NGfecifnet *) netp)->TxIdxAdd = 0;
((NGfecifnet *) netp)->TxIdxDel = 0;
/* *****************************************************************************************************
* Interrupt Mask Register
***************************************************************************************************** */
regs->FEC_EIMR = EIMR_TXF|EIMR_RXF;
/* *****************************************************************************************************
* clear interrupts
***************************************************************************************************** */
regs->FEC_EIR = ~0;
/* *****************************************************************************************************
* set mac address
***************************************************************************************************** */
regs->FEC_PALR = (NGuint)(NG_ETHIF_DATA( netp, eif_addr[0])<<24) |
(NG_ETHIF_DATA( netp, eif_addr[1])<<16) |(NG_ETHIF_DATA( netp, eif_addr[2])<<8) |
(NG_ETHIF_DATA( netp, eif_addr[3]));
regs->FEC_PAUR = (NGuint)(NG_ETHIF_DATA( netp, eif_addr[4])<<24) | (NG_ETHIF_DATA( netp, eif_addr[5])<<16);
/* *****************************************************************************************************
* set multicast filter
***************************************************************************************************** */
drvSetMulti( netp);
/* *****************************************************************************************************
* Set EMRBR - Max. Receive Buffer Length
***************************************************************************************************** */
regs->FEC_EMRBR = netp->if_dev2;
/* *****************************************************************************************************
* Receive Descriptor Ring Start Register
***************************************************************************************************** */
regs->FEC_ERDSR = (NGuint) &RxTxBD->RxBD[0];
/* *****************************************************************************************************
* Transmit Buffer Descriptor Ring - Start Register
***************************************************************************************************** */
regs->FEC_ETDSR = (NGuint) &RxTxBD->TxBD[0];
/* *****************************************************************************************************
* Receive Control Register - disable internal LoopBack
***************************************************************************************************** */
regs->FEC_RCR &= ~RCR_LOOP;
/* *****************************************************************************************************
* MII Speed Control Register
***************************************************************************************************** */
regs->FEC_MSCR = (0x00000005<<1);
/* *****************************************************************************************************
* MII mode (or lite), not 7 wire
***************************************************************************************************** */
regs->FEC_RCR |= RCR_MII_MODE;
/* *****************************************************************************************************
* Promiscuous mode - All frames are accepted regardless of address matching.
***************************************************************************************************** */
regs->FEC_RCR |= RCR_PROM;
regs->FEC_RCR &= 0x0000FFFF;
regs->FEC_RCR |= ((netp->if_dev2)<<16);
/* *****************************************************************************************************
* Full duplex operation
***************************************************************************************************** */
regs->FEC_TCR = TCR_FDEN;
/* *****************************************************************************************************
* Transmit FIFO Watermark - (0x02 = 192 bytes written)
***************************************************************************************************** */
regs->FEC_TFWR = 0x03;
/* *****************************************************************************************************
* install interrupt handlers
***************************************************************************************************** */
ngOSIsrAttach ( 194, (void (*)(void *)) drvHandler, netp );
ngOSIsrAttach ( 195, (void (*)(void *)) drvHandler, netp );
ngOSIsrAttach ( 196, (void (*)(void *)) drvHandler, netp );
/* *****************************************************************************************************
* MIB Control Register
***************************************************************************************************** */
regs->FEC_MIBC = 0x00000000;
/* *****************************************************************************************************
* Ethernet Control Register
* - enabled, device
***************************************************************************************************** */
regs->FEC_ECR |= ECR_ETHER_EN;
/* *****************************************************************************************************
* Receive Descriptor Active Register
***************************************************************************************************** */
regs->FEC_RDAR = RDAR_R_DES_ACTIVE;
return( NG_EOK);
}