?? mac.c
字號:
return (-5);
}
return 0;
#if DEBUG2
Timer2_init(); //調(diào)試延時
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);
/*發(fā)送數(shù)據(jù)*/
/*搜索一個可用的發(fā)送描述符*/
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數(shù)據(jù)到描述符中*/
Adress = ((MAC_BD + 4) + i*8);
temp_val = read_reg(Adress);
memcpy((CHAR *)(temp_val), TEMP_BUF_T, length);
/*設置描述符的bit15位,發(fā)送幀數(shù)據(jù)*/
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;
/*搜索接收數(shù)據(jù)的描述符*/
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))
{
/*獲得接收數(shù)據(jù)長度*/
//Adress = (MAC_BD + Tx_BD_Num*8) + i*8 ;
length = Temp_Rx_BD;
length = length>>16;
/*獲得該描述符的數(shù)據(jù)存放地址*/
Adress = Adress + 4;
Temp_Rx_Ram = read_reg(Adress);
//memcpy(TEMP_BUF_R, (CHAR *)(Temp_Rx_Ram), length); //減少一次內(nèi)存拷貝,加快響應速度
TEMP_BUF_R_Ptr = (CHAR *)(Temp_Rx_Ram);
/*重置相應的RX_BD用于接收數(shù)據(jù)*/
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);
}
/*將數(shù)據(jù)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中斷狀態(tài)寄存器*/
isr = read_reg(MAC_INTSRC);
temp2 = *(RP)(MAC_BD+8*64);
while(isr)
{
/*寫1清楚狀態(tài)位*/
write_reg(MAC_INTSRC, isr);
if(isr & (MAC_ISR_TXB | MAC_ISR_TXE | MAC_ISR_TXC)) /* pkt xmit or xmit error */
{
/*發(fā)送數(shù)據(jù)中斷*/
/*記錄發(fā)送錯誤或者發(fā)送成功*/
/*激活發(fā)送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))
{
/*接收數(shù)據(jù)中斷*/
/*記錄接收錯誤,或者接受成功*/
#if DEBUG2
time_count = get_timer(0);
#endif
/*調(diào)用Mac_Receive接收數(shù)據(jù)*/
Mac_Receive();
}
if(isr & MAC_ISR_BUSY)
{
/*RX_BD滿溢出*/
Mac_clear_Rx_BD();
}
/*讀取中斷狀態(tài)*/
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 + -