📄 eth860.c
字号:
IMMR->si_sicr &= ~(SICR_R1CS | SICR_T1CS | SICR_SC1 | SICR_GR1); /* Clear previous scc1 setting */
#if(ADS860)
#ifdef ETHER_LOOPBACK_MODE
IMMR->si_sicr |= (0x0000001B); /* Setup scc1 */
#else
IMMR->si_sicr |= (0x0000002C); /* Setup scc1 clk 1 & clk2 */
#endif
#elif(MPC860)
IMMR->si_sicr |= (0x0000003D); /* Setup scc1 clk2 & clk4 */
#else
#error
#endif
/* set up rx buffer descriptors - defined in mpc860ad.h */
CurrentRx = 0;
for (i=0; i<NumRxBDs; i++)
{
BUFFER_DESCRIPTORS[SCC1_RX_BD+i].flags = BD_SCC_ETH_RX_EMPTY | BD_SCC_ETH_RX_INTERRUPT;
BUFFER_DESCRIPTORS[SCC1_RX_BD+i].length = 0;
RxDCU[i] = os_alloc_packet_input(CFG_ETHERSIZE, ETH860_ALLOC); /* get a DCU */
BUFFER_DESCRIPTORS[SCC1_RX_BD+i].buffer = RxDCU[i]->data;
}
BUFFER_DESCRIPTORS[SCC1_RX_BD+i-1].flags |= BD_SCC_ETH_RX_WRAP;
for (i=0; i<NumTxBDs; i++)
{
BUFFER_DESCRIPTORS[SCC1_TX_BD+i].flags = BD_SCC_ETH_TX_PAD | BD_SCC_ETH_TX_INTERRUPT | BD_SCC_ETH_TX_LAST | BD_SCC_ETH_TX_CRC;
BUFFER_DESCRIPTORS[SCC1_TX_BD+i].length = 0;
BUFFER_DESCRIPTORS[SCC1_TX_BD+i].buffer = 0;
}
BUFFER_DESCRIPTORS[SCC1_TX_BD+NumTxBDs-1].flags |= BD_SCC_ETH_TX_WRAP;
sendbd = (BUFFER_DESCRIPTORS+SCC1_TX_BD);
sentbd = (BUFFER_DESCRIPTORS+SCC1_TX_BD);
/******************************************************* */
/* Common To All Protocols Parameter RAM Initialization */
/******************************************************* */
/*------------------------------------------ */
/* Set RXBD tbl start at Dual Port (16-164) */
/*------------------------------------------ */
recbd = BUFFER_DESCRIPTORS+SCC1_RX_BD;
bd_union.bd = recbd;
IMMR->PRAM[PAGE1].enet_scc.rbase = bd_union.rbase[1]; /* least sig word */
/*------------------------------------------- */
/* Set TXBD tbl start at Dual Port (16-164) */
/*------------------------------------------- */
bd_union.bd = sendbd;
IMMR->PRAM[PAGE1].enet_scc.tbase = bd_union.tbase[1]; /* least sig word */
IMMR->PRAM[PAGE1].enet_scc.rfcr = 0x18; /* Normal Operation and
Motorola byte ordering */
IMMR->PRAM[PAGE1].enet_scc.tfcr = 0x18; /* Motorola byte ordering,
Normal access */
/*----------------------------------------- */
/* Set MRBLR -- Max. Receive Buffer Length */
/* (Must be a multiple of 4, so use 1520) */
/*----------------------------------------- */
IMMR->PRAM[PAGE1].enet_scc.mrblr = ENET_MDMA;
/************************************************* */
/* Ethernet Specific Parameter RAM Initialization */
/************************************************* */
IMMR->PRAM[PAGE1].enet_scc.c_pres = ENET_C_PRES; /* CRC Preset */
IMMR->PRAM[PAGE1].enet_scc.c_mask = ENET_C_MASK; /* Constant MASK for CRC */
IMMR->PRAM[PAGE1].enet_scc.crcec = ALL_ZEROS; /* CRC Error Counter */
IMMR->PRAM[PAGE1].enet_scc.alec = ALL_ZEROS; /* Align. Error Counter */
IMMR->PRAM[PAGE1].enet_scc.disfc = ALL_ZEROS; /* Discard Frame Counter */
IMMR->PRAM[PAGE1].enet_scc.pads = ENET_PAD; /* Short Frame PAD Char. */
IMMR->PRAM[PAGE1].enet_scc.ret_lim = ENET_RET_LIM;/* Retry Limit Threshold */
IMMR->PRAM[PAGE1].enet_scc.mflr = ENET_MFLR; /* Max Frame Length Reg. */
IMMR->PRAM[PAGE1].enet_scc.minflr = ENET_MINFLR; /* Min Frame Length Reg. */
IMMR->PRAM[PAGE1].enet_scc.maxd1 = ENET_MDMA; /* Max DMA1 Length Reg. */
IMMR->PRAM[PAGE1].enet_scc.maxd2 = ENET_MDMA; /* Max DMA2 Length Reg. */
IMMR->PRAM[PAGE1].enet_scc.maxd = ENET_MDMA; /* added Max DMA2 Length Reg. */
IMMR->PRAM[PAGE1].enet_scc.dma_cnt = ENET_MDMA; /* added Max DMA2 Length Reg. */
IMMR->PRAM[PAGE1].enet_scc.max_b = ENET_MDMA; /* added Max DMA2 Length Reg. */
IMMR->PRAM[PAGE1].enet_scc.gaddr1 = ALL_ZEROS; /* Group Addr. Filter 1 */
IMMR->PRAM[PAGE1].enet_scc.gaddr2 = ALL_ZEROS; /* Group Addr. Filter 2 */
IMMR->PRAM[PAGE1].enet_scc.gaddr3 = ALL_ZEROS; /* Group Addr. Filter 3 */
IMMR->PRAM[PAGE1].enet_scc.gaddr4 = ALL_ZEROS; /* Group Addr. Filter 4 */
IMMR->PRAM[PAGE1].enet_scc.paddr_h = (myEthAddr.bytes[5]<<8) + myEthAddr.bytes[4];/* MSB */
IMMR->PRAM[PAGE1].enet_scc.paddr_m = (myEthAddr.bytes[3]<<8) + myEthAddr.bytes[2];
IMMR->PRAM[PAGE1].enet_scc.paddr_l = (myEthAddr.bytes[1]<<8) + myEthAddr.bytes[0]; /* LSB */
IMMR->PRAM[PAGE1].enet_scc.p_per = ALL_ZEROS; /* Persistence */
IMMR->PRAM[PAGE1].enet_scc.iaddr1 = ALL_ZEROS; /* Ind. Addr. Filter 1 */
IMMR->PRAM[PAGE1].enet_scc.iaddr2 = ALL_ZEROS; /* Ind. Addr. Filter 2 */
IMMR->PRAM[PAGE1].enet_scc.iaddr3 = ALL_ZEROS; /* Ind. Addr. Filter 3 */
IMMR->PRAM[PAGE1].enet_scc.iaddr4 = ALL_ZEROS; /* Ind. Addr. Filter 4 */
IMMR->PRAM[PAGE1].enet_scc.taddr_h = ALL_ZEROS; /* Temp Address (MSB) */
IMMR->PRAM[PAGE1].enet_scc.taddr_m = ALL_ZEROS; /* Temp Address */
IMMR->PRAM[PAGE1].enet_scc.taddr_l = ALL_ZEROS; /* Temp Address (LSB) */
/*---------------------------------------------- */
/* Issue Init Stop TX Command for SCC1. (16-10) */
/*---------------------------------------------- */
while ((IMMR->cp_cr & CPCR_FLG) != READY_TO_RX_CMD);
IMMR->cp_cr = CPCR_INIT_TX_RX_PARAMS |
CPCR_SCC1_CH |
CPCR_FLG; /* ISSUE COMMAND */
while ((IMMR->cp_cr & CPCR_FLG) != READY_TO_RX_CMD); /* remove */
/************* */
/* Interrupts */
/************* */
/*-------------------------------------------------------- */
/* Clear SCCE event Register by writing all 1's. (16-333) */
/*-------------------------------------------------------- */
IMMR->scc_regs[SCC1_REG].scc_scce = 0xffff;
/*--------------------------------------------------- */
/* Set SCCM for interrupts on TXE, RXF, TXB (16-333) */
/*--------------------------------------------------- */
IMMR->scc_regs[SCC1_REG].scc_sccm = SCCM_ETH_RXF | SCCM_ETH_TXB | SCCM_ETH_TXE; /* Enable these interrupts */
/*--------------------------------------------------- */
/* Enable SCC1 Interrupts to the CP Interrupt */
/* Controller by writing 0x40000000 to CIMR (16-483) */
/*--------------------------------------------------- */
IMMR->cpmi_cimr |= CIMR_SCC1;
/*---------------------------------------------------------------------- */
/* Clear Pending Interrupts in CIPR -- Clear bits by writing 1 (16-482) */
/*---------------------------------------------------------------------- */
IMMR->cpmi_cipr &= ~CIMR_SCC1; /* Clear any existing pending interrupt */
IMMR->cpmi_cisr = CIMR_SCC1; /* Clear any existing in-service interrupt */
/*------------------------------------------------------ */
/* Set Appropriate Interrupt Level Bit in SIMASK (12-6) */
/*------------------------------------------------------ */
IMMR->siu_simask = SIMASK_LVM4;
/*----------------------------------------------------- */
/* Initialize GSMR_H for normal operation (16-148) */
/*----------------------------------------------------- */
IMMR->scc_regs[SCC1_REG].scc_gsmr_h = 0;
/*-------------------------------------------------------- */
/* Initialize GSMR_L: (16-153) */
/* */
/* TCI = 1, TSNC = 10, TPL = 100, DIAG = 01, MODE = 1100 */
/*-------------------------------------------------------- */
IMMR->scc_regs[SCC1_REG].scc_gsmr_l = GSMR_DIAG_MODE | GSMR_L_TCI | GSMR_L_TPL_48 | GSMR_L_TPP_10 | GSMR_L_MODE_ETH;
/*------------------- */
/* Set DSR to 0xD555 */
/*------------------- */
IMMR->scc_regs[SCC1_REG].scc_dsr = ENET_DSR;
/*------------------------------------------------ */
/* Initialize PSMR: (16-325) */
/* */
/* IAM = 0, CRC = 10 (32-bit), LPB = 1, NIB = 101 */
/*------------------------------------------------ */
IMMR->scc_regs[SCC1_REG].scc_psmr = PSMR_PRO_MODE | PSMR_CRC_32 | PSMR_NIB_22 | PSMR_DIAG_MODE;
set_up_mpc860ads_board();
/* Now it's safe to enable RTS (16-308) (16-461) */
#if(ADS860)
IMMR->pip_pbodr &= ~PB_RTS1;
IMMR->pip_pbpar |= PB_RTS1;
IMMR->pip_pbdir |= PB_RTS1;
#elif(MPC860)
IMMR->pio_pcdir &= ~PC_SCCRTS1;
IMMR->pio_pcpar |= PC_SCCRTS1;
#else
#error
#endif
/*---------------------------------------------------------------------- */
/* Set the ENT/ENR bits in the GSMR -- Enable Transmit/Receive (16-153) */
/*---------------------------------------------------------------------- */
IMMR->scc_regs[SCC1_REG].scc_gsmr_l |= GSMR_L1_ENT | GSMR_L1_ENR;
return(TRUE);
}
/* ******************************************************************** */
/* close the packet driver interface. */
/* */
/* This routine is called when the device interface is no longer needed */
/* it should stop the driver from delivering packets to the upper levels */
/* and shut off packet delivery to the network. */
/* */
/* The address of this function must be placed into the "devices" table in */
/* iface.c either at compile time or before a device open is called. */
/* */
/* */
/* Non packet drivers should behave the same way. */
/* */
void eth860_close(PIFACE pi) /*__fn__*/
{
ether_enable_ads(0); /* disable ethernet on mpc860ads and mpc821ads boards */
}
word eth860_break(word sc)
{
return(sc);
}
/* ******************************************************************** */
/* Transmit. a packet over the packet driver interface. */
/* */
/* This routine is called when a packet needs sending. The packet contains a */
/* full ethernet frame to be transmitted. The length of the packet is */
/* provided. */
/* */
/*
*/
void eth860_txreset() /*__fn_*/
{
int i;
DISABLE8XX() /* clear interrupts */
/* Disable xmitter */
IMMR->scc_regs[SCC1_REG].scc_gsmr_l &= ~(GSMR_L_ENT);
ENABLE8XX()
for (i=0; i<NumTxBDs; i++)
{
BUFFER_DESCRIPTORS[SCC1_TX_BD+i].flags = BD_SCC_ETH_TX_PAD | BD_SCC_ETH_TX_INTERRUPT | BD_SCC_ETH_TX_LAST | BD_SCC_ETH_TX_CRC;
BUFFER_DESCRIPTORS[SCC1_TX_BD+i].length = 0;
BUFFER_DESCRIPTORS[SCC1_TX_BD+i].buffer = 0;
}
BUFFER_DESCRIPTORS[SCC1_TX_BD+NumTxBDs-1].flags |= BD_SCC_ETH_TX_WRAP;
sendbd = (BUFFER_DESCRIPTORS+SCC1_TX_BD);
sentbd = (BUFFER_DESCRIPTORS+SCC1_TX_BD);
bd_union.bd = sendbd;
IMMR->PRAM[PAGE1].enet_scc.tbase = bd_union.tbase[1]; /* least sig word */
/*------------------------------------------------------------------ */
/* (re) Initialize transmitter, Issue Init Stop TX Command. (16-10) */
/*------------------------------------------------------------------ */
while ((IMMR->cp_cr & CPCR_FLG) != READY_TO_RX_CMD);
IMMR->cp_cr = CPCR_INIT_TX_PARAMS | /* CPCR_INIT_TX_RX_PARAMS | */
CPCR_SCC1_CH |
CPCR_FLG; /* ISSUE COMMAND */
while ((IMMR->cp_cr & CPCR_FLG) != READY_TO_RX_CMD); /* remove */
/* Re Enable the transmitter and receiver */
IMMR->scc_regs[SCC1_REG].scc_gsmr_l |= GSMR_L_ENT;
}
BOOLEAN eth860_xmit_done(PIFACE pi, DCU msg, BOOLEAN success)
{
if (!success)
{ /* timeout! */
eth860_wait_ticks <<= 1; /* double the wait time and try again */
}
else
{
/* If ready is set or underrun is set stay in */
if (!(sendbd->flags & (BD_SCC_ETH_TX_UNDERRUN | BD_SCC_ETH_TX_READY)))
{
mcstats.packets_out += 1;
mcstats.bytes_out += DCUTOPACKET(msg)->length;
if (sendbd->flags & BD_SCC_ETH_TX_WRAP)
sendbd = (BUFFER_DESCRIPTORS+SCC1_TX_BD);
else
sendbd++;
return(TRUE); /* xmit done */
}
}
eth860_txreset();
if (eth860_retry == 4)
{
mcstats.errors_out += 1;
if (sendbd->flags & BD_SCC_ETH_TX_WRAP)
sendbd = (BUFFER_DESCRIPTORS+SCC1_TX_BD);
else
sendbd++;
return(TRUE); /* done due to error */
}
/* retry the send */
sendbd->buffer = DCUTODATA(msg);
sendbd->length = DCUTOPACKET(msg)->length;
/* clear status bits from previous xmit */
sendbd->flags &= ~(BD_SCC_ETH_TX_COLLISION |
BD_SCC_ETH_TX_HEARTBEAT |
BD_SCC_ETH_TX_LATE |
BD_SCC_ETH_TX_LIMIT |
BD_SCC_ETH_TX_RETRY_MASK |
BD_SCC_ETH_TX_UNDERRUN |
BD_SCC_ETH_TX_CARRIER);
sendbd->flags |= (BD_SCC_ETH_TX_READY | BD_SCC_ETH_TX_INTERRUPT);
eth860_retry++;
/* reset up the timeout value */
pi->xmit_done_timer = eth860_wait_ticks;
return(FALSE); /* not done */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -