📄 mac.c
字号:
return (-5);
}
return 0;
#if DEBUG2
Timer2_init(); //调试延时
delay_time_flage=0;
#endif
}
VOID Mac_TxHisr()
{
DV_DEVICE_ENTRY* device;
STATUS previous_int_value;
/*获得PHY设备指针*/
device = DEV_Get_Dev_By_Name("SEP4020_MAC");
if (device == NU_NULL)
return;
/* Lock out interrupts. */
//previous_int_value = NU_Control_Interrupts(NU_DISABLE_INTERRUPTS);
previous_int_value = NU_Control_Interrupts(NU_DISABLE_INTERRUPTS);
DEV_Recover_TX_Buffers (device);
/* If there is another item on the list, transmit it. */
if(device -> dev_transq.head)
{
/* Re-enable interrupts. */
NU_Control_Interrupts(previous_int_value);
/* Transmit the next packet. */
Mac_Transmit(device, device->dev_transq.head);
}
/* Re-enable interrupts. */
NU_Control_Interrupts(previous_int_value);
} /* MAC_TxHisr */
VOID Mac_RxHisr()
{
/* Let the upper layer know a good packet is here. */
NU_Set_Events(&Buffers_Available, (UNSIGNED)2, NU_OR);
Hisr_Activated = 0;
}
STATUS Mac_Transmit(DV_DEVICE_ENTRY *dev, NET_BUFFER *buf_ptr)
{
UINT32 length; /* The length of a packet*/
CHAR *FramePtr;
UINT32 Tx_BD_Num;
UINT32 Temp_Tx_BD;
UINT32 i;
UINT32 Temp_Rx_BD;
UINT32 Adress;
UINT32 temp_val;
//mask_irq(27);
//mask_irq(28);
//mask_all_irq();
length = 0;
FramePtr = TEMP_BUF_T;
/* #if INCLUDE_SNMP
Find out if this is a unicast or non-unicast packet, and update MIB.
if ((buf_ptr->mem_flags & NET_BCAST) || (buf_ptr->mem_flags & NET_MCAST))
SNMP_ifOutNUcastPkts_Inc(device->dev_unit + 1);
else
SNMP_ifOutUcastPkts_Inc(device->dev_unit + 1);
#endif*/
do
{
memcpy(FramePtr, buf_ptr->data_ptr, buf_ptr->data_len);
length += buf_ptr->data_len;
FramePtr += buf_ptr->data_len;
/* Move on to the next buffer. */
buf_ptr = buf_ptr->next_buffer;
} while (buf_ptr != 0);
/*发送数据*/
/*搜索一个可用的发送描述符*/
Tx_BD_Num = read_reg(MAC_TXBD_NUM);
Tx_BD_Num &=0x7F;
for(i=Tx_count;i<Tx_BD_Num;)
{
Adress = MAC_BD+ i*8;
Temp_Tx_BD = read_reg(Adress);
if(!(Temp_Tx_BD & 0x8000))
{
if(i == Tx_BD_Num-1) Tx_count = 0;
else Tx_count = i+1;
break;
}
if(i == Tx_BD_Num-1) i = 0;
else i++;
}
/*设置搜索到的可用描述符,copy数据到描述符中*/
Adress = ((MAC_BD + 4) + i*8);
temp_val = read_reg(Adress);
memcpy((CHAR *)(temp_val), TEMP_BUF_T, length);
/*设置描述符的bit15位,发送帧数据*/
length = length <<16;
if(i == Tx_BD_Num - 1)
length |= 0xF800;
else
length |= 0xD800;
Adress = (MAC_BD + i*8);
write_reg(Adress, length);
}
STATUS Mac_Receive()
{
UINT32 Tx_BD_Num;
UINT32 Temp_Rx_BD;
UINT32 i,j;
UINT32 length;
UINT32 Temp_Rx_Ram;
UINT32 pkt_size, bytes_left;
UINT32 Adress;
NET_BUFFER *buf_ptr;
CHAR *TEMP_BUF_R_Ptr;
DV_DEVICE_ENTRY *device;
device = DEV_Get_Dev_By_Name("SEP4020_MAC");
j=0;
/*搜索接收数据的描述符*/
Tx_BD_Num = read_reg(MAC_TXBD_NUM);
Tx_BD_Num &=0x7F;
//
// for(i=0;i<(128-Tx_BD_Num);i++)
while(1) //改变后的查询方式:从上一次的位置查询开始,直到第一个不可用的接收描述符为止
{
i = Rx_count;
Adress = (MAC_BD + Tx_BD_Num*8)+ i*8;
Temp_Rx_BD = read_reg(Adress);
if(!(Temp_Rx_BD & 0x8000))
{
/*获得接收数据长度*/
//Adress = (MAC_BD + Tx_BD_Num*8) + i*8 ;
length = Temp_Rx_BD;
length = length>>16;
/*获得该描述符的数据存放地址*/
Adress = Adress + 4;
Temp_Rx_Ram = read_reg(Adress);
//memcpy(TEMP_BUF_R, (CHAR *)(Temp_Rx_Ram), length); //减少一次内存拷贝,加快响应速度
TEMP_BUF_R_Ptr = (CHAR *)(Temp_Rx_Ram);
/*重置相应的RX_BD用于接收数据*/
Adress = Adress - 4;
if(i == (127-Tx_BD_Num))
write_reg(Adress, 0xe000);
else
write_reg(Adress, 0xc000);
/*获得BUFFER空间*/
/* Get the packet size fron the RxFD & allocate buffer(s) for it! */
pkt_size = length;
/* Allocate a buffer (or a chain of buffers) into which the Rx
** packet can be copied! */
if (pkt_size <= NET_PARENT_BUFFER_SIZE) /* One buffer case! */
{
buf_ptr = MEM_Buffer_Dequeue(&MEM_Buffer_Freelist);
}
else /* More than one buffer is needed! */
{
buf_ptr = MEM_Buffer_Chain_Dequeue(&MEM_Buffer_Freelist, pkt_size);
}
/*将数据copy到buffer*/
if (buf_ptr == NU_NULL)
{
//NU_Tcp_Log_Error (TCP_PARTITION_ERROR, TCP_RECOVERABLE,
// __FILE__, __LINE__);
/* Return that there was an error with a packet reception */
return(-1);
}
else
{
/* Put the head of the chain (or only one) on the incoming
** packet buffer list */
MEM_Buffer_Enqueue (&MEM_Buffer_List, buf_ptr);
/* Get the total number of bytes that must be copied */
bytes_left = pkt_size;
/* This sets Total Packet Length in the first (or only) buffer! */
buf_ptr->mem_total_data_len = pkt_size;
/* Set the device into the buffer header! */
buf_ptr->mem_buf_device = device;
/* Clear the flags field! */
buf_ptr->mem_flags = 0;
if (pkt_size <= NET_PARENT_BUFFER_SIZE) /* One buffer case. */
{
/* The MEM Buffer Dequeue function returns a Ptr to the Buffer's */
/* Data area at the TOP of the Buffer. */
buf_ptr->data_ptr = (UINT8 *) buf_ptr;
/* Data in this buffer, same as total for this case. */
buf_ptr->data_len = pkt_size;
/* Do the copy. */
memcpy(buf_ptr->data_ptr, (UINT8 *)TEMP_BUF_R_Ptr, pkt_size);
}
else /* More than one NET Buffer required! Pack the first one and */
{ /* enter the while loop to fill the remaining ones needed. */
/* Data area in the first buffer is less than in the rest. */
buf_ptr->data_len = NET_PARENT_BUFFER_SIZE;
/* The Ptr is to the Buffer's Data area at the TOP of the */
/* Buffer, so copy the buf_ptr to the Buffer's Data Ptr. */
buf_ptr->data_ptr = (UINT8 *) buf_ptr;
/* Do the copy. */
memcpy(buf_ptr->data_ptr, (UINT8 *)TEMP_BUF_R_Ptr,
NET_PARENT_BUFFER_SIZE);
bytes_left -= NET_PARENT_BUFFER_SIZE;
/* Advance data ptr to next block start. */
TEMP_BUF_R_Ptr += NET_PARENT_BUFFER_SIZE;
while (bytes_left > 0)
{
/* Move to the next buffer in the chain */
buf_ptr = (NET_BUFFER *) buf_ptr->next_buffer;
/* The Ptr is to the Buffer's Header start, NOT the Data area */
/* at the TOP of the Buffer, so copy the Adjusted Ptr to the */
/* Buffer's Data Ptr. */
buf_ptr->data_ptr = (UINT8 *) buf_ptr;
/* See if a Full Buffer is needed! Note that these buffers */
/* hold more data (0x218/536) since the me_bufhdr is not */
/* needed! */
if (bytes_left > NET_MAX_BUFFER_SIZE)
{
buf_ptr->data_len = NET_MAX_BUFFER_SIZE;
bytes_left -= NET_MAX_BUFFER_SIZE;
/* Do the copy. */
memcpy(buf_ptr->data_ptr, (UINT8 *)TEMP_BUF_R_Ptr,
buf_ptr->data_len);
/* Advance data ptr to next block start! */
TEMP_BUF_R_Ptr += NET_MAX_BUFFER_SIZE;
}
else
{
buf_ptr->data_len = bytes_left;
bytes_left = 0;
/* Do the copy. */
memcpy(buf_ptr->data_ptr,
(UINT8 *)TEMP_BUF_R_Ptr,
buf_ptr->data_len);
}
} /* END: while (bytes_left > 0) */
} /* END: else (more than one NET Buffer needed) */
}
if(Rx_count ==(127-Tx_BD_Num)) Rx_count=0;
else Rx_count++;
}
else break;
}
/*激活接收HSR*/
if (!Hisr_Activated)
{
Hisr_Activated = 0;
/* Activate the Receive HISR. */
NU_Activate_HISR (&Mac_Rcv);
}
// end else (buffer is not NULL)
}
void Mac_clear_Rx_BD()
{
UINT32 Adress;
int i;
for(i=0;i<0x40;i++)
{
Adress = (MAC_BD+0x40*8)+i*8;
if (i == (0x40 - 1))
write_reg(Adress, 0xe000);
else
write_reg(Adress, 0xc000);
}
Rx_count=0;
}
VOID MAC_LISR(INT VECTOR)
{
mask_irq(28);
Mac_Interrupt();
unmask_irq(28);
}
VOID Mac_Interrupt()
{
UINT32 isr;
UINT32 temp2;
/*读取Mac中断状态寄存器*/
isr = read_reg(MAC_INTSRC);
temp2 = *(RP)(MAC_BD+8*64);
while(isr)
{
/*写1清楚状态位*/
write_reg(MAC_INTSRC, isr);
if(isr & (MAC_ISR_TXB | MAC_ISR_TXE | MAC_ISR_TXC)) /* pkt xmit or xmit error */
{
/*发送数据中断*/
/*记录发送错误或者发送成功*/
/*激活发送HSR*/
// Mac_Txd();
NU_Activate_HISR(&Mac_Xmit);
#if DEBUG2
if(delay_time_flage==1)
{
time_count = get_timer(time_count);
*(RP)dis_address = time_count;
dis_address+=4;
delay_time_flage=0;
}
#endif
}
if(isr & (MAC_ISR_RXB | MAC_ISR_RXE | MAC_ISR_RXC))
{
/*接收数据中断*/
/*记录接收错误,或者接受成功*/
#if DEBUG2
time_count = get_timer(0);
#endif
/*调用Mac_Receive接收数据*/
Mac_Receive();
}
if(isr & MAC_ISR_BUSY)
{
/*RX_BD满溢出*/
Mac_clear_Rx_BD();
}
/*读取中断状态*/
isr = read_reg(MAC_INTSRC);
}
}
VOID Mac_Config()
{
}
STATUS Mac_Ioctl(DV_DEVICE_ENTRY *dev, INT option, DV_REQ *d_req)
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -