if_mcf5272.c
来自「开放源码实时操作系统源码.」· C语言 代码 · 共 1,887 行 · 第 1/5 页
C
1,887 行
/* This routine updates the Ethernet statistics counters. This method */
/* is called by eCos every second. */
static void one_second_alarm_func(cyg_handle_t alarm, cyg_addrword_t data)
{
#define WRAP_SUBTRACT(_VAL1_,_VAL2_) \
({unsigned long val;if (_VAL1_ >= _VAL2_) val = _VAL1_ - _VAL2_; \
else val=(0-_VAL2_)+_VAL1_; val;})
((MCF5272_fec_priv_data_t*)data)->diag_counters.rx_bytes_cnt_sec =
WRAP_SUBTRACT(
((MCF5272_fec_priv_data_t*)data)->diag_counters.rx_bytes_cnt,
((MCF5272_fec_priv_data_t*)data)->diag_info_sup.old_rx_bytes_cnt);
((MCF5272_fec_priv_data_t*)data)->diag_counters.tx_bytes_cnt_sec =
WRAP_SUBTRACT(
((MCF5272_fec_priv_data_t*)data)->diag_counters.tx_bytes_cnt,
((MCF5272_fec_priv_data_t*)data)->diag_info_sup.old_tx_bytes_cnt);
((MCF5272_fec_priv_data_t*)data)->diag_counters.rx_pk_cnt_sec =
WRAP_SUBTRACT(
((MCF5272_fec_priv_data_t*)data)->diag_counters.rx_pk_cnt,
((MCF5272_fec_priv_data_t*)data)->diag_info_sup.old_rx_pk_cnt);
((MCF5272_fec_priv_data_t*)data)->diag_counters.tx_pk_cnt_sec =
WRAP_SUBTRACT(
((MCF5272_fec_priv_data_t*)data)->diag_counters.tx_pk_cnt,
((MCF5272_fec_priv_data_t*)data)->diag_info_sup.old_tx_pk_cnt);
((MCF5272_fec_priv_data_t*)data)->diag_info_sup.old_rx_bytes_cnt =
((MCF5272_fec_priv_data_t*)data)->diag_counters.rx_bytes_cnt;
((MCF5272_fec_priv_data_t*)data)->diag_info_sup.old_tx_bytes_cnt =
((MCF5272_fec_priv_data_t*)data)->diag_counters.tx_bytes_cnt;
((MCF5272_fec_priv_data_t*)data)->diag_info_sup.old_rx_pk_cnt =
((MCF5272_fec_priv_data_t*)data)->diag_counters.rx_pk_cnt;
((MCF5272_fec_priv_data_t*)data)->diag_info_sup.old_tx_pk_cnt =
((MCF5272_fec_priv_data_t*)data)->diag_counters.tx_pk_cnt;
}
/* Retrieve the stats information. */
void MCF5272_get_stats(struct eth_drv_sc *sc, MCF5272_FEC_DIAG* stats)
{
memcpy(stats, &PMCF5272_FEC_DATA(sc)->diag_counters,
sizeof (MCF5272_FEC_DIAG));
/* Retrieve the number of available buffer descriptors and the */
/* minimum value. */
PMCF5272_FEC_DATA(sc)->diag_counters.tx_free_bd_cnt =
NUM_TXBDS - PBUF_INFO(sc)->num_busy_bd;
PMCF5272_FEC_DATA(sc)->diag_counters.tx_free_min_bd_cnt =
NUM_TXBDS - PBUF_INFO(sc)->max_num_busy_bd;
}
/*****************************************************************************
The following functions provide an interface directly to the
ethernet driver for applications that wish to circumvent the IP stack.
Applications that wish to take advantage of this should override
these routine with their own. Leaving these routines as default routes
all data through the IP stack.
*****************************************************************************/
/*****************************************************************************
eth_rx_pkt_filter -- Ethernet receive packet filter
This is an ethernet packet filter function that allows the application
to receive raw ethernet frames from the driver. The return value of this
function determines whether or not to pass the packet to the IP stack.
We declare it weak so that other routine can override it.
INPUT:
pkt: Pointer to the packet.
pkt_len: The length of the packet including all headers, the 32-bit
Ethernet CRC, and any Ethernet frame padding.
OUTPUT:
RETURN VALUE:
true: Do not send the packet to the IP stack.
false: Send the packet to the IP stack.
*****************************************************************************/
int_t eth_rx_pkt_filter(u8_t * pkt, uint_t pkt_len)
{
/* Always return false by default. */
return false;
}
/*****************************************************************************
eth_tx_check -- Watch transmitting Ethernet packets
The driver calls this routine before transmitting packets from the
IP stack. It provides a hook for applications to watch all packets that
the IP stack transmits.
We declare it weak so that other routine can override it.
INPUT:
sg_list: Pointer to the scatter-gather list.
sg_len: The number of scatter-gather entries in the list.
OUTPUT:
RETURN VALUE:
None
*****************************************************************************/
void eth_tx_check(struct eth_drv_sg * sg_list, unsigned int sg_len)
{
/* Do nothing by default. */
}
/*****************************************************************************
eth_send -- Transmit a raw Ethernet packet
This function sends a packet to the Ethernet controller thus
passing the eCos IP stack.
Note that the application must reuse the buffer parameters to this
function until the driver releases the buffer with the eth_send_done()
function.
INPUT:
sg_list: Pointer to the scatter-gather list to send.
sg_len: The size of the scatter-gather list.
tag: A value that we pass as a parameter to eth_send_done()
function when the FEC has completed sending the packet.
OUTPUT:
RETURN VALUE:
true: if the packet is successfully queued to the device driver's
queue.
false : If the routine fails to send the packet.
*****************************************************************************/
int_t eth_send(struct eth_drv_sg* sg_list, unsigned int sg_len,
int total_len,
unsigned long tag)
{
int_t success;
cyg_uint32 s;
s = cyg_splsoftnet();
/* If there is enough buffer descriptors, then send the packet. */
/* Otherwise, throw the packet away and return a false value. */
if (NUM_TXBDS - PBUF_INFO(&MCF5272_fec_sc)->num_busy_bd > sg_len)
{
/* Call the common send routine to send the packet. */
MCF5272_fec_common_send(&MCF5272_fec_sc,
sg_list,
sg_len,
total_len,
tag,
TX_KEY_USER);
success = true;
}
else
{
/* Fail to send the packet. */
success = false;
}
/* Release the Ethernet driver lock. */
cyg_splx(s);
return success;
}
/*****************************************************************************
eth_send_done -- eth_send callback
The driver calls this function when it has sent out the packet. The
parameter tag is the same value as the tag value when the caller calls the
eth_send to send the packet.
We declare it weak so that other routine can override it.
INPUT:
tag: A value that we pass as a parameter to eth_send_done()
function when the FEC has completed sending the packet.
OUTPUT:
RETURN VALUE:
None
*****************************************************************************/
void eth_send_done(unsigned long tag)
{
}
#if 0
/* Defined Ethernet Frame Types */
#define FRAME_IP (0x0800)
#define FRAME_ARP (0x0806)
#define FRAME_RARP (0x8035)
/* Offset and size of protocol headers */
#define ETH_HDR_OFFSET 0 /* Ethernet header at the top of the frame */
#define ETH_HDR_SIZE 14
/* Assign a protocol number for the loop test */
static uint16 eth_type = 0x0300;
/* Global variable containing length of data to transmit */
static uint16 data_length = 512;
/* Transmit data size of each transmti buffer descriptor. */
#define TX_BUFFER_SIZE (576) /* must be divisible by 16 */
void
fec_start_loopback_test(void)
{
/* Initalize the buffer descriptors. */
nbuf_init(&MCF5272_fec_priv_data.nbuffer);
/* Initalize the Ethernet controllder device. */
MCF5272_fec_init(&MCF5272_fec_netdev);
}
/********************************************************************/
static void
loop_fill_buffers(void)
{
/* Fill all the buffers in the TX buffer ring with a unique data pattern */
uint16 index, pattern, i;
static unsigned char output_buffer[NUM_TXBDS][TX_BUFFER_SIZE];
uint_t data_length = TX_BUFFER_SIZE;
for (i = 0; i < NUM_TXBDS; i++)
{
MCF5272_fec_priv_data.nbuffer.TxNBUF[i].data = output_buffer[i];
switch (i % 8)
{
/* Load buffers 0 through 3 with a single data patterns */
case (0):
memset(&MCF5272_fec_priv_data.nbuffer.TxNBUF[i].data[ETH_HDR_SIZE],0x55,data_length);
break;
case (1):
memset(&MCF5272_fec_priv_data.nbuffer.TxNBUF[i].data[ETH_HDR_SIZE],0xAA,data_length);
break;
case (2):
memset(&MCF5272_fec_priv_data.nbuffer.TxNBUF[i].data[ETH_HDR_SIZE],0x00,data_length);
break;
case (3):
memset(&MCF5272_fec_priv_data.nbuffer.TxNBUF[i].data[ETH_HDR_SIZE],0xFF,data_length);
break;
/* Buffer[4]: Load increasing walking ones */
case (4):
pattern = 1;
for (index = 0; index < data_length; index++)
{
if (pattern == 0x0100)
pattern = 0x01;
MCF5272_fec_priv_data.nbuffer.TxNBUF[i].data[index] = (uint8)pattern;
pattern <<= 1;
}
break;
/* Buffer[5]: Load decreasing walking ones */
case(5):
pattern = 0x80;
for (index = 0; index < data_length; index++)
{
if (pattern == 0x00)
pattern = 0x80;
MCF5272_fec_priv_data.nbuffer.TxNBUF[i].data[index] = (uint8)pattern;
pattern >>= 1;
}
break;
/* Buffer[6]: Load "Increment from 0" pattern */
case (6):
for (index = 0; index < data_length; index++)
MCF5272_fec_priv_data.nbuffer.TxNBUF[i].data[index] = (uint8) ((index-14)%256);
break;
/* Buffer[7]: Load "Decrement from 255" pattern */
case (7):
for (index = 0; index < data_length; index++)
MCF5272_fec_priv_data.nbuffer.TxNBUF[i].data[index] = (uint8)(255- ((index-14)%256));
break;
}
}
}
/********************************************************************/
void
loop_handler(void)
{
/* This is the loop specific RX handler called from the interrupt */
/* receive routine. This routine gets bound to the loop protocol */
/* (0x0300) by a call to nif_bind_protocol() and is then called in */
/* fec_receive(). This function simply checks to make sure that the */
/* receive buffer matches the transmit buffer. */
int i;
/* Compare what I received to what I transmitted */
for (i = 0; i < (data_length + ETH_HDR_SIZE); i++)
{
if (TxBuffer[fec_nif->f_rx % NUM_TXBDS].data[i] != pNbuf->data[i])
{
/* Increment reception error count */
fec_nif->f_rx_err++;
}
}
/* Increment reception count */
fec_nif->f_rx++;
/* Update progress indicator */
if (!(fec_nif->f_rx % 200))
{
ihash = (ihash + 1) % 4;
diag_printf("\b%c",hash[ihash]);
}
return;
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?