📄 lan_am79c973.c
字号:
* ------------- * This service registers a mac-layer defined receive-handler in the * LAN-drivers ISR-context to allow for interrupt controlled receive * frame processing in the network stack. No external buffer * administration is required as the protocol-layers are responsible for * handling buffer-allocation and data copy-ing to the allocated buffer * payload area. At return from 'receive' handler, the LAN-drivers * local RX-buffer (packet) is released for re-use. After 'open' * has been called, the LAN-driver's 'read' service will call the * registered receive-handler by any frame reception with direct * reference to the LAN-drivers packet space and no read data will be * delivered in the IO-descriptor. * * * * Parameters : * ------------ * * 'major', IN, major device number * 'minor', IN, not used * 'p_param', IN, LAN variable of type, t_LAN_IO_desc. * * * Return values : * --------------- * 'OK'(=0) * * * ************************************************************************/staticINT32 LAN_AM79C973_open( UINT32 major, /* IN: major device number */ UINT32 minor, /* IN: minor device number */ t_LAN_OPEN_desc *p_param ) /* IN: receive handler reference */{ UINT32 old_ie ; /* register user defined receive handler */ old_ie = sys_disable_int() ; usr_receive = p_param->receive ; if(old_ie) sys_enable_int(); return( OK ) ;}/************************************************************************ * * LAN_AM79C973_read * Description : * ------------- * This service polls the specified LAN interface for any received frame. * If any frame has been received, it will be read into the user allocated * variable, *p_param; if none present, completion = 'ERROR_LAN_NO_FRAME' * will be returned. * * * Parameters : * ------------ * * 'major', IN, major device number * 'minor', IN, minor device number for multi device drivers * 'p_param', INOUT, LAN variable of type, t_LAN_IO_desc. * * * Return values : * --------------- * * 'OK'(=0) * 'ERROR_LAN_NO_FRAME': no frame present on this LAN interface * 'ERROR_LAN_COMM_ERROR': communication error detected * * ************************************************************************/staticINT32 LAN_AM79C973_read( UINT32 major, /* IN: major device number */ UINT32 minor, /* IN: minor device number */ t_LAN_IO_desc *p_param ) /* INOUT: LAN frame */{ /* dummy function, as NET_poll, still calls this function */ return( OK ) ;}/************************************************************************ * * LAN_AM79C973_write * Description : * ------------- * This service requests transmission of a frame on the LAN interface. It is the caller's * responsibility to fill in all information including the destination and source addresses and * the frame type. The length parameter gives the number of bytes in the ethernet frame. * The routine will not return until the frame has been transmitted or an error has occured. If * the frame transmits successfully, OK is returned. If an error occured, a message is sent to * the serial port and the routine returns non-zero. * * * Parameters : * ------------ * * 'major', IN, major device number * 'minor', IN, minor device number for multi device drivers * 'p_param', INOUT, LAN variable of type, t_LAN_IO_desc. * * * Return values : * --------------- * * 'OK'(=0) * 'ERROR_LAN_COMM_ERROR': communication error detected * * ************************************************************************/staticINT32 LAN_AM79C973_write( UINT32 major, /* IN: major device number */ UINT32 minor, /* IN: minor device number */ t_LAN_IO_desc *p_param ) /* OUT: frame to transmit */{ int i ; int tdreidx ; UINT32 status, status2, control ; UINT8 *pb = p_param->data ; UINT32 blen = p_param->length ; t_LAN_AM79C973_device *pdevice ; UINT32 rcode, old_ie; if ( LAN_AM79C973_state == LAN_AM79C973_DRIVER_IS_STOPPED ) { return( ERROR_LAN_TXM_ERROR ) ; } /* get device context for this minor device */ pdevice = &minor_device[minor] ; tdreidx = pdevice->NextTDREIndex; i = 0 ; old_ie = sys_disable_int() ; while (1) { /* get status */ status = REG( pdevice->TXDRE[tdreidx], TDE_WORD1 ) ; status = LE32_TO_CPU( status ) ; if ( ( ((status) & TDE_WORD1_OWN_MSK) >> TDE_WORD1_OWN_SHF) == HOST_IS_OWNER ) { /* Check for error. */ if (status & TDE_WORD1_ERR_MSK) { /* Some transmit error has been detected */ pdevice->status.tx_errors++; if (status & TDE_WORD1_BPE_MSK ) pdevice->status.tx_bus_parity_errors++; status2 = REG( pdevice->TXDRE[tdreidx], TDE_WORD2 ) ; status2 = LE32_TO_CPU( status2 ) ; if (status2 & TDE_WORD2_LCOL_MSK ) pdevice->status.tx_window_errors++; if (status2 & TDE_WORD2_LCAR_MSK ) pdevice->status.tx_carrier_errors++; if (status2 & TDE_WORD2_UFLO_MSK ) pdevice->status.tx_fifo_errors++; pdevice->status.collisions += ((status2 & TDE_WORD2_TRC_MSK) >> TDE_WORD2_TRC_SHF ) ; } /* Clear error word for next transmit */ REG( pdevice->TXDRE[tdreidx], TDE_WORD2 ) = 0 ; /* Copy data and request transmission of new buffer */ memcpy( (void*)pdevice->TxBuffer[tdreidx], pb, blen ) ; control = ( (TDE_WORD1_OWN_MSK) | (TDE_WORD1_STP_MSK) | (TDE_WORD1_ENP_MSK) | (TDE_WORD1_ONES_MSK) | (((-blen) << TDE_WORD1_BCNT_SHF) & TDE_WORD1_BCNT_MSK) ) ; control = CPU_TO_LE32( control ) ; REG( pdevice->TXDRE[tdreidx], TDE_WORD1 ) = control ; pdevice->status.tx_bytes += blen ; pdevice->status.tx_packets++; /* Request immediate transmission */ CSR_WRITE( pdevice->p79C973Regs, 0, 0x0048 ) tdreidx++ ; if (tdreidx == LAN_AM79C973_TDRE_COUNT) tdreidx = 0 ; pdevice->NextTDREIndex = tdreidx ; rcode = OK ; break ; } else { /* wait 1 ms */ sys_wait_ms( 1 ) ; /* wait at most 1 second */ i++ ; if ( i > 1000 ) { pdevice->status.tx_errors++; pdevice->status.tx_timeout_errors++; /* re-init driver and controller */ LAN_AM79C973_init( 0, 0, NULL ) ; rcode = ERROR_LAN_TXM_ERROR ; break ; } } } if(old_ie) sys_enable_int(); return( rcode ) ;}/************************************************************************ * * LAN_AM79C973_ctrl * Description : * ------------- * This service requests special service via 'ctrl' * * * Parameters : * ------------ * * 'major', IN, major device number * 'minor', IN, minor device number for multi device drivers * 'p_param', INOUT, LAN variable of type, t_LAN_IO_desc. * * * Return values : * --------------- * * 'OK'(=0) * * ************************************************************************/staticINT32 LAN_AM79C973_ctrl( UINT32 major, /* IN: major device number */ UINT32 minor, /* IN: minor device number */ t_LAN_CTRL_desc *p_param ) /* IN-OUT: */{ t_LAN_AM79C973_device *pdevice ; UINT32 old_ie ; /* get device context for this minor device */ pdevice = &minor_device[minor] ; switch( p_param->command ) { case LAN_CTRL_DISPLAY_STATISTICS:#ifdef ETH_DEBUG //LAN_AM79C973_dump_regs( pdevice ) ; LAN_AM79C973_dump_descriptors( pdevice ) ; LAN_AM79C973_dump_device( pdevice ) ;#endif LAN_AM79C973_MII_status( pdevice ) ; LAN_AM79C973_dump_status( pdevice ) ; break ; case LAN_CTRL_STOP_CONTROLLER: LAN_AM79C973_stop( pdevice ) ; break ; case LAN_CTRL_START_CONTROLLER: /* re-init driver and controller */ old_ie = sys_disable_int() ; LAN_AM79C973_init( 0, 0, NULL ) ; if(old_ie) sys_enable_int(); break ; default: break ; } return( OK ) ;}/************************************************************************ * * LAN_AM79C973_dump_regs * Description : * ------------- * Dump all AM79C973 LAN controller registers * * * Parameters : * ------------ * * 'pdevice', IN, reference for this device context * * * Return values : * --------------- * * 'OK'(=0) * * * ************************************************************************/#ifdef ETH_DEBUGstaticINT32 LAN_AM79C973_dump_regs( t_LAN_AM79C973_device *pdevice ){ UINT32 rvar ; volatile void *plan ; plan = pdevice->p79C973Regs ; BCR_READ( plan, 2, rvar ) printf(" BCR2 = %08x\n", rvar ) ; BCR_READ( plan, 4, rvar ) printf(" BCR4 = %08x\n", rvar ) ; BCR_READ( plan, 5, rvar ) printf(" BCR5 = %08x\n", rvar ) ; BCR_READ( plan, 6, rvar ) printf(" BCR6 = %08x\n", rvar ) ; BCR_READ( plan, 7, rvar ) printf(" BCR7 = %08x\n", rvar ) ; BCR_READ( plan, 9, rvar ) printf(" BCR9 = %08x\n", rvar ) ; BCR_READ( plan, 18, rvar ) printf(" BCR18 = %08x\n", rvar ) ; BCR_READ( plan, 22, rvar ) printf(" BCR22 = %08x\n", rvar ) ; BCR_READ( plan, 23, rvar ) printf(" BCR23 = %08x\n", rvar ) ; BCR_READ( plan, 24, rvar ) printf(" BCR24 = %08x\n", rvar ) ; BCR_READ( plan, 25, rvar ) printf(" BCR25 = %08x\n", rvar ) ; BCR_READ( plan, 26, rvar ) printf(" BCR26 = %08x\n", rvar ) ; BCR_READ( plan, 27, rvar ) printf(" BCR27 = %08x\n", rvar ) ; BCR_READ( plan, 32, rvar ) printf(" BCR32 = %08x\n", rvar ) ; BCR_READ( plan, 33, rvar ) printf(" BCR33 = %08x\n", rvar ) ; BCR_READ( plan, 35, rvar ) printf(" BCR35 = %08x\n", rvar ) ; BCR_READ( plan, 36, rvar ) printf(" BCR36 = %08x\n", rvar ) ; BCR_READ( plan, 37, rvar ) printf(" BCR37 = %08x\n", rvar ) ; BCR_READ( plan, 38, rvar ) printf(" BCR38 = %08x\n", rvar ) ; BCR_READ( plan, 39, rvar ) printf(" BCR39 = %08x\n", rvar ) ; BCR_READ( plan, 40, rvar ) printf(" BCR40 = %08x\n", rvar ) ; BCR_READ( plan, 41, rvar ) printf(" BCR41 = %08x\n", rvar ) ; BCR_READ( plan, 42, rvar ) printf(" BCR42 = %08x\n", rvar ) ; BCR_READ( plan, 43, rvar ) printf(" BCR43 = %08x\n", rvar ) ; BCR_READ( plan, 44, rvar ) printf(" BCR44 = %08x\n", rvar ) ; BCR_READ( plan, 45, rvar ) printf(" BCR45 = %08x\n", rvar ) ; BCR_READ( plan, 46, rvar ) printf(" BCR46 = %08x\n", rvar ) ; BCR_READ( plan, 47, rvar ) printf(" BCR47 = %08x\n", rvar ) ; CSR_READ( plan, 12, rvar ) printf(" CSR12 = %08x\n", rvar ) ; CSR_READ( plan, 13, rvar ) printf(" CSR13 = %08x\n", rvar ) ; CSR_READ( plan, 14, rvar ) printf(" CSR14 = %08x\n", rvar ) ; CSR_READ( plan, 116, rvar ) printf(" CSR116 = %08x\n", rvar ) ; return( OK ) ;}#endif/************************************************************************ * * LAN_AM79C973_dump_status * Description : * ------------- * Dump all AM79C973 LAN controller statistics * * * Parameters : * ------------ * * 'pdevice', IN, reference for this device context * * * Return values : * --------------- * * 'OK'(=0) * * * ************************************************************************/staticvoid LAN_AM79C973_dump_status( t_LAN_AM79C973_device *pdevice ){ sprintf( msg, " Packets received: %u\n\r", pdevice->status.rx_packets ) ; PUTS( DEFAULT_PORT, msg ) ; sprintf( msg, " Packets transmitted: %u\n\r", pdevice->status.tx_packets ) ; PUTS( DEFAULT_PORT, msg ) ; sprintf( msg, " Bytes received: %u\n\r", pdevice->status.rx_bytes ) ; PUTS( DEFAULT_PORT, msg ) ; sprintf( m
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -