📄 ne2kif.c
字号:
p = low_level_input(netif);
/* no packet could be read, silently ignore this */
if (p == NULL) return;
/* points to packet payload, which starts with an Ethernet header */
ethhdr = p->payload;
#if LINK_STATS
lwip_stats.link.recv++;
#endif /* LINK_STATS */
switch(htons(ethhdr->type)) {
/* IP packet? */
case ETHTYPE_IP:
/* update ARP table */
etharp_ip_input(netif, p);
/* skip Ethernet header */
pbuf_header(p, -(14+ETH_PAD_SIZE));
/* pass to network layer */
netif->input(p, netif);
break;
case ETHTYPE_ARP:
/* pass p to ARP module */
etharp_arp_input(netif, ne2k_if->ethaddr, p);
break;
default:
pbuf_free(p);
p = NULL;
break;
}
}
/*
* low_level_input():
*
* Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
*/
static struct pbuf *
low_level_input(struct netif *netif)
{
u16_t packetLength, Count, remote_Addr;
u8_t *buf, PDHeader[4];
u8_t curr, this_frame, next_frame;
struct pbuf *p, *q, *r;
EN_CMD = (u8_t) (EN_PAGE1 + EN_NODMA + EN_START);
curr = (u8_t) EN1_CURR;
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_START);
this_frame = (u8_t) EN0_BOUNDARY + 1;
if (this_frame >= RX_STOP_PG)
this_frame = RX_START_PG;
//---------- get the first 4 bytes from AX88796 ---------
(void) read_AX88796(PDHeader, (u16_t)(this_frame<<8), 4);
//----- Store real length, set len to packet length - header ---------
packetLength = ((unsigned) PDHeader[2] | (PDHeader[3] << 8 )) - 4; // minus PDHeader[4]
next_frame = (u8_t) (this_frame + 1 + ((packetLength + 4) >> 8));
// Bad frame!
if ((PDHeader[1] != (u8_t)next_frame) && (PDHeader[1] != (u8_t)(next_frame + 1))
&& (PDHeader[1] != (u8_t)(next_frame - RX_STOP_PG + RX_START_PG))
&& (PDHeader[1] != (u8_t)(next_frame + 1 - RX_STOP_PG + RX_START_PG)))
{
EN0_BOUNDARY = (u8_t) (curr - 1);
return NULL;
}
// Bogus Packet Size
if (packetLength > MAX_PACKET_SIZE || packetLength < MIN_PACKET_SIZE)
{
next_frame = PDHeader[1];
EN0_BOUNDARY = (u8_t) (next_frame-1);
return NULL;
}
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_START);
EN0_ISR = (u8_t) ENISR_RDC; // clear the RDC bit
remote_Addr = (u16_t)((this_frame << 8) + 4);
if ((remote_Addr + packetLength + ETH_PAD_SIZE) > (u16_t)(RX_STOP_PG<<8)) {
p = pbuf_alloc(PBUF_RAW, (u16_t)(RX_STOP_PG<<8) - remote_Addr, PBUF_POOL); /* length of buf */
packetLength -= (u16_t)(RX_STOP_PG<<8) - remote_Addr - ETH_PAD_SIZE;
} else {
p = pbuf_alloc(PBUF_RAW, packetLength+ETH_PAD_SIZE, PBUF_POOL); /* length of buf */
packetLength = 0;
}
if(p != NULL) { /* We iterate over the pbuf chain until we have read the entire packet into the pbuf. */
for(q = p; q != NULL; q= q->next){ /* Read enough bytes to fill this pbuf in the chain. The avaliable data in the pbuf is given by the q->len variable. */
buf = q->payload;
Count = q->len;
if (q == p){ // if it's the first pbuf in chain...
buf += ETH_PAD_SIZE;
Count -= ETH_PAD_SIZE; // pad in Eth_hdr struct
}
remote_Addr = read_AX88796(buf, remote_Addr, Count);
#if LINK_STATS
lwip_stats.link.recv++;
#endif /* LINK_STATS */
} //for(q = p; q != NULL; q= q->next)
} //if(p != NULL)
else
{ // p == NULL
#if LINK_STATS
lwip_stats.link.memerr++;
lwip_stats.link.drop++;
#endif /* LINK_STATS */
}
if (packetLength) // ring buffer cycled
{
remote_Addr = (u16_t)(RX_START_PG << 8);
r = pbuf_alloc(PBUF_RAW, packetLength, PBUF_POOL); /* length of buf */
if(r != NULL) { /* We iterate over the pbuf chain until we have read the entire packet into the pbuf. */
for(q = r; q != NULL; q= q->next){ /* Read enough bytes to fill this pbuf in the chain. The avaliable data in the pbuf is given by the q->len variable. */
buf = q->payload;
Count = q->len;
remote_Addr = read_AX88796(buf, remote_Addr, Count);
} //for
// link pbuf p & r
pbuf_cat(p, r);
}
else // r == NULL
{
#if LINK_STATS
lwip_stats.link.memerr++;
lwip_stats.link.drop++;
#endif
}
} // if (packetLength)
next_frame = PDHeader[1];
EN0_BOUNDARY = (u8_t) (next_frame-1);
return p;
}
/**
* read_AX88796.
*/
u16_t read_AX88796(u8_t * buf, u16_t remote_Addr, u16_t Count)
{
u8_t flagOdd=0;
#ifndef QDMA_Enabled
u16_t loop;
#endif
flagOdd = (Count & 0x0001); // set Flag if Count is odd.
Count -= flagOdd;
EN0_RCNTLO = (u8_t) (Count & 0xff);
EN0_RCNTHI = (u8_t) (Count >> 8);
EN0_RSARLO = (u8_t) (remote_Addr & 0xff);
EN0_RSARHI = (u8_t) (remote_Addr >> 8);
EN_CMD = (u8_t) (EN_PAGE0 + EN_RREAD + EN_START);
remote_Addr += Count;
Count = Count>>1;
#ifdef QDMA_Enabled
*(u32_t *)QDMA_SRC = (u32_t) &EN_DATA;
*(u32_t *)QDMA_DST = (u32_t) buf;
*(u32_t *)QDMA_CNT = (u32_t) Count;
*(u32_t *)QDMA_IDX = 0x00000000;
*(u32_t *)QDMA_S_OPT = 0x28200001;
buf += Count*2;
#else
for (loop=0;loop < Count ;loop++){
*(u16_t *)buf = EN_DATA ;
buf += 2;
}
#endif //QDMA_Enabled
while ((EN0_ISR & ENISR_RDC) == 0);
EN0_ISR = (u8_t) ENISR_RDC;
if (flagOdd) {
EN0_RCNTLO = 0x01;
EN0_RCNTHI = 0x00;
EN0_RSARLO = (u8_t) (remote_Addr & 0xff);
EN0_RSARHI = (u8_t) (remote_Addr >> 8);
EN_CMD = (u8_t) (EN_PAGE0 + EN_RREAD + EN_START);
remote_Addr += 1;
*(u8_t *)buf = *(u8_t *)(Base_ADDR+0x10) ;
while ((EN0_ISR & ENISR_RDC) == 0);
EN0_ISR = (u8_t) ENISR_RDC;
}
return remote_Addr;
}
/*----------------------------------------------------------------------------------------
****************************************************************************************
----------------------------------------------------------------------------------------*/
/**
* ne2k_rx_err.
*/
void ne2k_rx_err(void)
{
u8_t curr;
EN_CMD = (u8_t) (EN_PAGE1 + EN_NODMA + EN_STOP);
curr = (u8_t) EN1_CURR;
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);
EN0_BOUNDARY = (u8_t) curr-1;
}
/**
* ne2k_rx.
*/
void ne2k_rx(void)
{
u8_t curr,bnry,loopCnt = 0;
while(loopCnt < 10) {
EN_CMD = (u8_t) (EN_PAGE1 + EN_NODMA + EN_STOP);
curr = (u8_t) EN1_CURR;
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);
bnry = (u8_t) EN0_BOUNDARY + 1;
if (bnry >= RX_STOP_PG)
bnry = RX_START_PG;
if (curr == bnry) break;
ne2k_input(ne2k_if_netif);
loopCnt++;
}
}
/*---*---*---*---*---*---*---*
* void ne2k_isr(void)
* can be int 4 5 6 or 7
*---*---*---*---*---*---*---*/
void ne2k_isr(void)
{
DSP_C6x_Save();
OSIntEnter();
if (OSIntNesting == 1)
{
OSTCBCur->OSTCBStkPtr = (OS_STK *) DSP_C6x_GetCurrentSP();
}
/* You can enable Interrupt again here,
if want to use nested interrupt..... */
//------------------------------------------------------------
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);
//outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP,NE_CR);
EN0_IMR = (u8_t) 0x00;//close
// ram overflow interrupt
if (EN0_ISR & ENISR_OVER) {
EN0_ISR = (u8_t) ENISR_OVER; // clear interrupt
}
// error transfer interrupt ,NIC abort tx due to excessive collisions
if (EN0_ISR & ENISR_TX_ERR) {
EN0_ISR = (u8_t) ENISR_TX_ERR; // clear interrupt
//temporarily do nothing
}
// Rx error , reset BNRY pointer to CURR (use SEND PACKET mode)
if (EN0_ISR & ENISR_RX_ERR) {
EN0_ISR = (u8_t) ENISR_RX_ERR; // clear interrupt
ne2k_rx_err();
}
//got packet with no errors
if (EN0_ISR & ENISR_RX) {
EN0_ISR = (u8_t) ENISR_RX;
ne2k_rx();
}
//Transfer complelte, do nothing here
if (EN0_ISR & ENISR_TX){
EN0_ISR = (u8_t) ENISR_TX; // clear interrupt
}
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);
EN0_ISR = (u8_t) 0xff; // clear ISR
EN0_IMR = (u8_t) (ENISR_OVER + ENISR_RX + ENISR_RX_ERR);
//open nic for next packet
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_START);
DSK6713_LED_toggle(2); //added for DSK6713 2005.10.21
//--------------------------------------------------------
OSIntExit();
DSP_C6x_Resume();
asm (" nop 5"); //important!
// this can avoid a stack error when compile with the optimization!
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -