📄 net_mac.c
字号:
return( rcode ) ;
}
/************************************************************************
*
* NET_MAC_close
* Description :
* -------------
*
* Close a MAC-SAP.
*
*
* Parameters :
* ------------
*
* mac_sp_hd service provider defined handle
*
*
* Return values :
* ---------------
*
* 'ERROR_NET_MAC_INVALID_HANDLE', invalid handle
* 'OK'(=0), SAP has been closed
*
*
************************************************************************/
UINT32 NET_MAC_close( UINT32 mac_sp_hd ) /* service provider defined handle */
{
/* validate handle */
IF_UPPER( ERROR_NET_MAC_INVALID_HANDLE, mac_sp_hd, MAC_SAP_COUNT)
/* close SAP */
sap_context[mac_sp_hd].mac_sap_state = MAC_SAP_STATE_CLOSED ;
sap_context[mac_sp_hd].mac_sap = MAC_SAP_UNDEFINED ;
sap_context[mac_sp_hd].mac_usr_receive = NULL ;
return(OK) ;
}
/************************************************************************
*
* NET_MAC_send
* Description :
* -------------
*
* Request the MAC module to send a frame, linked
* to a certain 'SAP' to a specified MAC-destination address.
*
*
* Parameters :
* ------------
*
* 'mac_sp_hd', OUT, handle to lookup a registered SAP context
* 'dst_adr', OUT, destination mac address
* 'length', OUT, length of frame to send
* 'data', OUT, address to start of frame to be send
*
*
* Return values :
* ---------------
* 'OK'(=0), successfull initialization
*
************************************************************************/
UINT32 NET_MAC_send( UINT32 mac_sp_hd, /* service provider defined handle */
t_mac_addr *dst_adr, /* destination mac address */
UINT32 length, /* total length of frame to send */
UINT8 *data ) /* pointer to start of frame */
{
UINT32 old_ie ;
t_LAN_IO_desc desc ;
UINT32 rcode ;
UINT8 *p ;
UINT16 sap ;
int i ;
/* validate handle */
IF_UPPER( ERROR_NET_MAC_INVALID_HANDLE, mac_sp_hd, MAC_SAP_COUNT)
/* validate state */
if ( sap_context[mac_sp_hd].mac_sap_state != MAC_SAP_STATE_OPEN )
{
return( ERROR_NET_MAC_SAP_CLOSED ) ;
}
/* we have a registered SAP context */
sap = sap_context[mac_sp_hd].mac_sap ; /* get SAP (in 'BE' format) */
/* Fill-in MAC header of frame */
p = (data + MAC_HEADER_BASE) ;
put6( dst_adr[0], p ) ; /* fill-in destination MAC-address */
put6( mac_station_adr[0], p ) ; /* fill-in our MAC-address */
put2( sap, p ) ; /* fill-in SAP */
#ifdef NET_DEBUG
p = data ;
printf("NET_MAC_send:") ;
for (i=0; i<length; i++)
{
if (i%16 == 0)
{
printf("\n %02x",*p++ ) ;
}
else
{
printf(" %02x",*p++ ) ;
}
}
printf("\n" ) ;
#endif
/* Check for broadcast */
if ( !memcmp( data, mac_broadcast_adr, SYS_MAC_ADDR_SIZE ) )
{
/* This is for our station; i.e. loopback */
old_ie = sys_disable_int() ;
memcpy( lbbuf, data, length ) ;
rcode = NET_MAC_receive( length, lbbuf ) ;
if(old_ie) sys_enable_int();
}
/* Check for loopback */
if ( !memcmp( data, mac_station_adr, SYS_MAC_ADDR_SIZE ) )
{
/* This is for our station; i.e. loopback */
old_ie = sys_disable_int() ;
memcpy( lbbuf, data, length ) ;
rcode = NET_MAC_receive( length, lbbuf ) ;
if(old_ie) sys_enable_int();
}
else
{
/* Call driver to send this frame */
desc.length = length ;
desc.data = data ;
rcode = IO_write( en0_major_device, en0_minor_device, &desc ) ;
}
/* return completion */
return( rcode ) ;
}
/************************************************************************
*
* NET_MAC_poll
* Description :
* -------------
* Poll the MAC module to receive any frame from driver.
* (Note: is not used by ISR-handled reception.)
*
*
* Parameters :
* ------------
* -
*
*
* Return values :
* ---------------
* 'OK'
*
************************************************************************/
UINT32 NET_MAC_poll( void )
{
UINT32 rcode ;
t_LAN_IO_desc desc ;
/* we just call the driver to poll and let the driver
call 'NET_MAC_receive' in case of any received frame */
desc.length = 0 ;
desc.data = NULL ;
rcode = IO_read( en0_major_device, en0_minor_device, &desc ) ;
return( rcode ) ;
}
/************************************************************************
* Implementation : Static functions
************************************************************************/
/************************************************************************
*
* NET_MAC_receive
* Description :
* -------------
* In "RX-frame receive int. mode", this function is called from
* the LAN-driver ISR, whenever it receives an Ethernet frame.
*
* In "RX-frame receive polled mode", this function will still
* be called from the LAN-driver, but in this case, the call
* gets started when NET_MAC_poll() calls the LAN-driver 'read'
* entry.
*
* It must check for any SAP's registered to handle the addressed
* SAP and if one found, the registered receive handler is called.
*
*
*
* Parameters :
* ------------
* 'length': length of received ethernet frame
* 'data': pointer for received ethernet frame (in driver's space)
*
*
* Return values :
* ---------------
* 'OK'
*
************************************************************************/
static
UINT32 NET_MAC_receive( UINT32 length,
UINT8 *data )
{
UINT32 rcode ;
t_mac_usr_receive receive ;
UINT8 *p ;
UINT16 sap ;
int i ;
#ifdef NET_DEBUG
p = data ;
printf("NET_MAC_receive:") ;
for (i=0; i<length; i++)
{
if (i%16 == 0)
{
printf("\n %02x",*p++ ) ;
}
else
{
printf(" %02x",*p++ ) ;
}
}
printf("\n" ) ;
#endif
/* validate frame size */
if (length > MAC_MAX_FRAME_SIZE)
{
return( ERROR_NET_MAC_INVALID_LENGTH ) ;
}
/* get sap of this received frame, and keep it in 'BE'-format */
p = (data + MAC_HEADER_BASE + MAC_HEADER_TYPE) ;
get2( p, sap) ;
/* search the SAP table to match this 'sap' */
for ( i = 0; i <MAC_SAP_COUNT ; i++ )
{
if ( sap_context[i].mac_sap == sap )
{
if ( sap_context[i].mac_sap_state == MAC_SAP_STATE_OPEN )
{
/* we have a registered SAP context, call user */
receive = sap_context[i].mac_usr_receive ;
p = (data + MAC_HEADER_BASE + MAC_HEADER_SRCADR) ;
rcode = (*receive)( (t_mac_addr*) p,
length,
data ) ;
#ifdef NET_DEBUG
printf("NET_MAC_receive, rcode = %x\n", rcode ) ;
#endif
return( rcode ) ;
}
}
}
return( ERROR_NET_MAC_NO_SAP ) ;
}
/************************************************************************
*
* NET_MAC_alloc_sap
* Description :
* -------------
* Allocate a MAC SAP, register user context and return a sp-handle.
*
*
* Parameters :
* ------------
* 'mac_sap_id', IN, value of MAC-'type' to bind for
* 'mac_usr_receive', IN, user-receive function to be registered
* 'mac_sp_hd', OUT, handle of MAC to be used by user by call
* of 'send'
*
*
* Return values :
* ---------------
* 'ERROR_NET_MAC_NO_FREE_SAP', No SAP entry could be allocated
* 'OK' = 0x00:
*
*
************************************************************************/
static
UINT32 NET_MAC_alloc_sap(
UINT16 mac_sap_id, /* 'type'-field of mac-header
always in 'cpu' format */
t_mac_usr_receive mac_usr_receive, /* user defined receive handler */
UINT32 *mac_sp_hd ) /* service provider defined handle */
{
int i ;
/* allocate a free MAC SAP table entry */
for ( i = 0; i <MAC_SAP_COUNT ; i++)
{
if ( sap_context[i].mac_sap_state == MAC_SAP_STATE_CLOSED )
{
/* save SAP context in allocated entry */
sap_context[i].mac_sap_state = MAC_SAP_STATE_OPEN ;
sap_context[i].mac_sap = CPU_TO_BE16( mac_sap_id ) ;
sap_context[i].mac_usr_receive = mac_usr_receive ;
*mac_sp_hd = i ;
return( OK ) ;
}
}
/* we should not arrive here */
return( ERROR_NET_MAC_NO_FREE_SAP ) ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -