/** @file Copyright (c) 2016 - 2017, Socionext Inc. All rights reserved.
Copyright (c) 2017, Linaro, Ltd. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "ogma_config.h" #include "ogma_internal.h" #include "ogma_basic_access.h" /********************************************************************** * Constant definitions **********************************************************************/ /** * Clock range index for F_GMAC4MT::GAR::CR field. */ #if (OGMA_CONFIG_GMAC_CLK_HZ < 35 * OGMA_CLK_MHZ) #define OGMA_CLOCK_RANGE_IDX OGMA_GMAC_GAR_REG_CR_25_35_MHZ #elif (OGMA_CONFIG_GMAC_CLK_HZ < 60 * OGMA_CLK_MHZ) #define OGMA_CLOCK_RANGE_IDX OGMA_GMAC_GAR_REG_CR_35_60_MHZ #elif (OGMA_CONFIG_GMAC_CLK_HZ < 100 * OGMA_CLK_MHZ) #define OGMA_CLOCK_RANGE_IDX OGMA_GMAC_GAR_REG_CR_60_100_MHZ #elif (OGMA_CONFIG_GMAC_CLK_HZ < 150 * OGMA_CLK_MHZ) #define OGMA_CLOCK_RANGE_IDX OGMA_GMAC_GAR_REG_CR_100_150_MHZ #elif (OGMA_CONFIG_GMAC_CLK_HZ < 250 * OGMA_CLK_MHZ) #define OGMA_CLOCK_RANGE_IDX OGMA_GMAC_GAR_REG_CR_150_250_MHZ #else #define OGMA_CLOCK_RANGE_IDX OGMA_GMAC_GAR_REG_CR_250_300_MHZ #endif /********************************************************************** * Local function declarations **********************************************************************/ static void ogma_set_phy_reg_sub ( ogma_ctrl_t *ctrl_p, ogma_uint8 reg_addr, ogma_uint16 value ); static ogma_uint16 ogma_get_phy_reg_sub ( ogma_ctrl_t *ctrl_p, ogma_uint8 reg_addr ); #ifdef OGMA_CONFIG_USE_DUMP_GMAC_STAT void ogma_dump_gmac_stat (ogma_ctrl_t *ctrl_p); #endif /* OGMA_CONFIG_USE_DUMP_GMAC_STAT */ static void ogma_set_phy_target_mmd_reg_addr ( ogma_ctrl_t *ctrl_p, ogma_uint8 dev_addr, ogma_uint16 reg_addr ); static void ogma_set_phy_mmd_reg_sub ( ogma_ctrl_t *ctrl_p, ogma_uint8 dev_addr, ogma_uint16 reg_addr, ogma_uint16 value ); static ogma_uint16 ogma_get_phy_mmd_reg_sub ( ogma_ctrl_t *ctrl_p, ogma_uint8 dev_addr, ogma_uint16 reg_addr ); /********************************************************************** * Function definitions **********************************************************************/ ogma_err_t ogma_start_gmac ( ogma_handle_t ogma_handle, ogma_bool rx_flag, ogma_bool tx_flag ) { ogma_uint32 value; ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; pfdep_err_t pfdep_err; ogma_err_t ogma_err; if ( ctrl_p == NULL) { return OGMA_ERR_PARAM; } if ( !ctrl_p->param.use_gmac_flag) { return OGMA_ERR_NOTAVAIL; } if ( !ctrl_p->gmac_mode_valid_flag) { return OGMA_ERR_INVALID; } if ( ( !rx_flag) && ( !tx_flag) ) { return OGMA_ERR_OK; } if ( ctrl_p->gmac_rx_running_flag && ctrl_p->gmac_tx_running_flag) { return OGMA_ERR_OK; } if ( ( rx_flag && ctrl_p->gmac_rx_running_flag) && !tx_flag) { return OGMA_ERR_OK; } if ( ( tx_flag && ctrl_p->gmac_tx_running_flag) && !rx_flag ) { return OGMA_ERR_OK; } pfdep_print( PFDEP_DEBUG_LEVEL_DEBUG_MORE_DETAILED, "%s call.\n", __func__); if ( (! ctrl_p->gmac_rx_running_flag) && (! ctrl_p->gmac_tx_running_flag) ) { /* Initializes F_GMAC4MT */ if ( ctrl_p->gmac_mode.link_speed == OGMA_PHY_LINK_SPEED_1G) { /* Writes 0 to FGMAC4 MCR */ ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_MCR, 0); } else { /* Writes PS bit to FGMAC4 MCR */ ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_MCR, OGMA_GMAC_MCR_10M_HALF);/* 10M half Reset */ } /* F_GMAC4MT soft reset*/ if ( ( ogma_err = ogma_softreset_gmac( ctrl_p)) != OGMA_ERR_OK) { return ogma_err; } /* MAC desc soft reset */ ogma_write_reg( ctrl_p, OGMA_REG_ADDR_MAC_DESC_SOFT_RST, OGMA_MAC_DESC_SOFT_RST_SOFT_RST); /* Wait MAC desc soft reset */ pfdep_err = pfdep_msleep( 1); if ( pfdep_err == PFDEP_ERR_INTERRUPT) { pfdep_print( PFDEP_DEBUG_LEVEL_FATAL, "An error occurred at ogma_start_gmac.\n"); pfdep_print( PFDEP_DEBUG_LEVEL_FATAL, "Wait for MAC desc soft reset error.\n"); return OGMA_ERR_INTERRUPT; } /* Check MAC desc soft reset done */ if ( ( ogma_read_reg( ctrl_p, OGMA_REG_ADDR_MAC_DESC_SOFT_RST) & OGMA_MAC_DESC_SOFT_RST_SOFT_RST) != 0) { pfdep_print( PFDEP_DEBUG_LEVEL_FATAL, "ogma_start_gmac():MAC desc soft reset timeout. Try Again.\n"); return OGMA_ERR_AGAIN; } /* MAC desc init */ ogma_write_reg( ctrl_p, OGMA_REG_ADDR_MAC_DESC_INIT, OGMA_MAC_DESC_INIT_REG_INIT); /* Wait MAC desc init done */ pfdep_err = pfdep_msleep( 1); if ( pfdep_err == PFDEP_ERR_INTERRUPT) { pfdep_print( PFDEP_DEBUG_LEVEL_FATAL, "An error occurred at ogma_start_gmac().\n"); pfdep_print( PFDEP_DEBUG_LEVEL_FATAL, "Wait for MAC desc init done error.\n"); return OGMA_ERR_INTERRUPT; } /* Check MAC desc init done */ if ( ( ogma_read_reg( ctrl_p, OGMA_REG_ADDR_MAC_DESC_INIT) & OGMA_MAC_DESC_INIT_REG_INIT) != 0) { pfdep_print( PFDEP_DEBUG_LEVEL_FATAL, "ogma_start_gmac():MAC desc init timeout. Try Again.\n"); return OGMA_ERR_AGAIN; } /* set BMR */ ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_BMR, OGMA_GMAC_BMR_REG_COMMON); /* set RDLAR */ ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_RDLAR, OGMA_GMAC_RDLAR_REG_COMMON); /* set TDLAR*/ ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_TDLAR, OGMA_GMAC_TDLAR_REG_COMMON); /* set MFFR*/ ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_MFFR, 0x80000001UL); /* calc MCR setting val */ value = ( ctrl_p->gmac_mode.half_duplex_flag ? OGMA_GMAC_MCR_REG_HALF_DUPLEX_COMMON : OGMA_GMAC_MCR_REG_FULL_DUPLEX_COMMON); if ( ctrl_p->gmac_mode.link_speed != OGMA_PHY_LINK_SPEED_1G) { value |= OGMA_GMAC_MCR_REG_PS; } if ( ( ctrl_p->param.gmac_config.phy_interface != OGMA_PHY_INTERFACE_GMII ) && ( ctrl_p->gmac_mode.link_speed == OGMA_PHY_LINK_SPEED_100M) ) { value |= OGMA_GMAC_MCR_REG_FES; } /* set CST bit */ value |= OGMA_GMAC_MCR_REG_CST; /* set JE bit */ value |= OGMA_GMAC_MCR_REG_JE; if ( ctrl_p->param.gmac_config.phy_interface == OGMA_PHY_INTERFACE_RGMII) { /* set ignore in-band-status watch option. force tx clk out. */ value |= 0x40000000U; } /* set MCR */ ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_MCR, value); if ( ctrl_p->gmac_mode.flow_ctrl_enable_flag) { /* Set Flow Control Threshold */ value = ( ctrl_p->gmac_mode.flow_ctrl_stop_threshold << 16) | ctrl_p->gmac_mode.flow_ctrl_start_threshold; ogma_write_reg( ctrl_p, OGMA_REG_ADDR_MAC_FLOW_TH, value); /* Set Flow Control Threshold F_GMAC4MT*/ value = ( ctrl_p->gmac_mode.pause_time << 16) | OGMA_GMAC_FCR_REG_RFE | OGMA_GMAC_FCR_REG_TFE; ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_FCR, value); } } if ( ( rx_flag && (! ctrl_p->gmac_rx_running_flag) ) || ( tx_flag && (! ctrl_p->gmac_tx_running_flag) ) ) { /* Read F_GMAC4MT OMR*/ value = ogma_get_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_OMR); if ( rx_flag && (! ctrl_p->gmac_rx_running_flag) ) { value |= OGMA_GMAC_OMR_REG_SR; ctrl_p->gmac_rx_running_flag = OGMA_TRUE; } if ( tx_flag && (! ctrl_p->gmac_tx_running_flag) ) { value |= OGMA_GMAC_OMR_REG_ST; ctrl_p->gmac_tx_running_flag = OGMA_TRUE; } /* set OMR*/ ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_OMR, value); } return OGMA_ERR_OK; } ogma_err_t ogma_stop_gmac ( ogma_handle_t ogma_handle, ogma_bool rx_flag, ogma_bool tx_flag ) { ogma_uint32 value; ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if ( ctrl_p == NULL) { return OGMA_ERR_PARAM; } if ( !ctrl_p->param.use_gmac_flag) { return OGMA_ERR_NOTAVAIL; } if ( ( !rx_flag) && ( !tx_flag) ) { return OGMA_ERR_OK; } pfdep_print( PFDEP_DEBUG_LEVEL_DEBUG_MORE_DETAILED, "%s call.\n", __func__); if ( ( rx_flag && ctrl_p->gmac_rx_running_flag) || ( tx_flag && ctrl_p->gmac_tx_running_flag) ) { /* Read F_GMAC4MT OMR*/ value = ogma_get_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_OMR); if ( rx_flag && ctrl_p->gmac_rx_running_flag) { value &= (~OGMA_GMAC_OMR_REG_SR); ctrl_p->gmac_rx_running_flag = OGMA_FALSE; } if ( tx_flag && ctrl_p->gmac_tx_running_flag) { value &= (~OGMA_GMAC_OMR_REG_ST); ctrl_p->gmac_tx_running_flag = OGMA_FALSE; } /* set F_GMAC4MT OMR*/ ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_OMR, value); } #ifdef OGMA_CONFIG_USE_DUMP_GMAC_STAT ogma_dump_gmac_stat (ctrl_p); #endif /* OGMA_CONFIG_USE_DUMP_GMAC_STAT */ return OGMA_ERR_OK; } ogma_err_t ogma_set_gmac_mode ( ogma_handle_t ogma_handle, const ogma_gmac_mode_t *gmac_mode_p ) { ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if ( ( ctrl_p == NULL) || ( gmac_mode_p == NULL) ) { return OGMA_ERR_PARAM; } if ( !ctrl_p->param.use_gmac_flag) { return OGMA_ERR_NOTAVAIL; } if ( ( ctrl_p->gmac_rx_running_flag) || ( ctrl_p->gmac_tx_running_flag) ) { return OGMA_ERR_BUSY; } if ( ( gmac_mode_p->link_speed != OGMA_PHY_LINK_SPEED_1G ) && ( gmac_mode_p->link_speed != OGMA_PHY_LINK_SPEED_100M) && ( gmac_mode_p->link_speed != OGMA_PHY_LINK_SPEED_10M ) ) { return OGMA_ERR_DATA; } if ( ( gmac_mode_p->link_speed == OGMA_PHY_LINK_SPEED_1G) && ( gmac_mode_p->half_duplex_flag) ) { return OGMA_ERR_DATA; } if ( gmac_mode_p->half_duplex_flag && gmac_mode_p->flow_ctrl_enable_flag) { return OGMA_ERR_DATA; } if ( gmac_mode_p->flow_ctrl_enable_flag) { if ( ( gmac_mode_p->flow_ctrl_start_threshold == 0) || ( gmac_mode_p->flow_ctrl_start_threshold > OGMA_FLOW_CTRL_START_THRESHOLD_MAX) ) { return OGMA_ERR_DATA; } if ( ( gmac_mode_p->flow_ctrl_stop_threshold < gmac_mode_p->flow_ctrl_start_threshold) || ( gmac_mode_p->flow_ctrl_stop_threshold > OGMA_FLOW_CTRL_STOP_THRESHOLD_MAX) ) { return OGMA_ERR_DATA; } if ( gmac_mode_p->pause_time < OGMA_FLOW_CTRL_PAUSE_TIME_MIN) { return OGMA_ERR_DATA; } } pfdep_print( PFDEP_DEBUG_LEVEL_DEBUG_MORE_DETAILED, "%s call.\n", __func__); pfdep_memcpy( ( void *)&ctrl_p->gmac_mode, ( void *)gmac_mode_p, sizeof( ogma_gmac_mode_t) ); ctrl_p->gmac_mode_valid_flag = OGMA_TRUE; return OGMA_ERR_OK; } static void ogma_set_phy_reg_sub ( ogma_ctrl_t *ctrl_p, ogma_uint8 reg_addr, ogma_uint16 value ) { ogma_uint32 cmd; ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_GDR, value); cmd = ( ( ctrl_p->param.phy_addr << OGMA_GMAC_GAR_REG_SHIFT_PA) | ( reg_addr << OGMA_GMAC_GAR_REG_SHIFT_GR) | ( OGMA_CLOCK_RANGE_IDX << OGMA_GMAC_GAR_REG_SHIFT_CR) | OGMA_GMAC_GAR_REG_GW | OGMA_GMAC_GAR_REG_GB); ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_GAR, cmd); while ( ( ogma_get_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_GAR) & OGMA_GMAC_GAR_REG_GB) != 0) { ; } } void ogma_set_phy_reg ( ogma_handle_t ogma_handle, ogma_uint8 reg_addr, ogma_uint16 value ) { ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if (( ctrl_p == NULL) || ( !ctrl_p->param.use_gmac_flag) || ( reg_addr >= 32) ) { pfdep_print( PFDEP_DEBUG_LEVEL_FATAL, "An error occurred at ogma_set_phy_reg.\nPlease set valid argument.\n"); return; } ogma_set_phy_reg_sub( ctrl_p, reg_addr, value); } static ogma_uint16 ogma_get_phy_reg_sub ( ogma_ctrl_t *ctrl_p, ogma_uint8 reg_addr ) { ogma_uint32 cmd; cmd = ( ( ctrl_p->param.phy_addr << OGMA_GMAC_GAR_REG_SHIFT_PA) | ( reg_addr << OGMA_GMAC_GAR_REG_SHIFT_GR) | ( OGMA_CLOCK_RANGE_IDX << OGMA_GMAC_GAR_REG_SHIFT_CR) | OGMA_GMAC_GAR_REG_GB); ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_GAR, cmd); while ( ( ogma_get_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_GAR) & OGMA_GMAC_GAR_REG_GB) != 0) { ; } return (ogma_uint16)ogma_get_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_GDR); } ogma_uint16 ogma_get_phy_reg ( ogma_handle_t ogma_handle, ogma_uint8 reg_addr ) { ogma_uint16 value; ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if ( ( ctrl_p == NULL) || ( !ctrl_p->param.use_gmac_flag) || ( reg_addr >= 32) ) { pfdep_print( PFDEP_DEBUG_LEVEL_FATAL, "An error occurred at ogma_get_phy_reg.\nPlease set valid argument.\n"); return 0; } value = ogma_get_phy_reg_sub(ctrl_p, reg_addr); return value; } #if ( defined(OGMA_CONFIG_USE_READ_GMAC_STAT) || defined(OGMA_CONFIG_USE_DUMP_GMAC_STAT) ) static const struct { ogma_uint32 addr; ogma_char *name_p; } ogma_gmac_mmc_reg_info[] = { {OGMA_GMAC_REG_ADDR_MMC_INTR_RX , "MMC_INTR_RX"}, {OGMA_GMAC_REG_ADDR_MMC_INTR_TX , "MMC_INTR_TX"}, {OGMA_GMAC_REG_ADDR_MMC_INTR_MASK_RX , "MMC_INTR_MASK_RX"}, {OGMA_GMAC_REG_ADDR_MMC_INTR_MASK_TX , "MMC_INTR_MASK_TX"}, {OGMA_GMAC_REG_ADDR_TXOCTETCOUNT_GB , "TXOCTETCOUNT_GB"}, {OGMA_GMAC_REG_ADDR_TXFRAMECOUNT_GB , "TXFRAMECOUNT_GB"}, {OGMA_GMAC_REG_ADDR_TXBROADCASTFRAMES_G , "TXBROADCASTFRAMES_G"}, {OGMA_GMAC_REG_ADDR_TXMULTICASTFRAMES_G , "TXMULTICASTFRAMES_G"}, {OGMA_GMAC_REG_ADDR_TX64OCTETS_GB , "TX64OCTETS_GB"}, {OGMA_GMAC_REG_ADDR_TX65TO127OCTETS_GB , "TX65TO127OCTETS_GB"}, {OGMA_GMAC_REG_ADDR_TX128TO255OCTETS_GB , "TX128TO255OCTETS_GB"}, {OGMA_GMAC_REG_ADDR_TX256TO511OCTETS_GB , "TX256TO511OCTETS_GB"}, {OGMA_GMAC_REG_ADDR_TX512TO1023OCTETS_GB, "TX512TO1023OCTETS_GB"}, {OGMA_GMAC_REG_ADDR_TX1024TOMAXOCTETS_GB, "TX1024TOMAXOCTETS_GB"}, {OGMA_GMAC_REG_ADDR_TXUNICASTFRAMES_GB , "TXUNICASTFRAMES_GB"}, {OGMA_GMAC_REG_ADDR_TXMULTICASTFRAMES_GB, "TXMULTICASTFRAMES_GB"}, {OGMA_GMAC_REG_ADDR_TXBROADCASTFRAMES_GB, "TXBROADCASTFRAMES_GB"}, {OGMA_GMAC_REG_ADDR_TXUNDERFLOWERROR , "TXUNDERFLOWERROR"}, {OGMA_GMAC_REG_ADDR_TXSINGLECOL_G , "TXSINGLECOL_G"}, {OGMA_GMAC_REG_ADDR_TXMULTICOL_G , "TXMULTICOL_G"}, {OGMA_GMAC_REG_ADDR_TXDEFERRED , "TXDEFERRED"}, {OGMA_GMAC_REG_ADDR_TXLATECOL , "TXLATECOL"}, {OGMA_GMAC_REG_ADDR_TXEXESSCOL , "TXEXESSCOL"}, {OGMA_GMAC_REG_ADDR_TXCARRIERERRROR , "TXCARRIERERRROR"}, {OGMA_GMAC_REG_ADDR_TXOCTETCOUNT_G , "TXOCTETCOUNT_G"}, {OGMA_GMAC_REG_ADDR_TXFRAMECOUNT_G , "TXFRAMECOUNT_G"}, {OGMA_GMAC_REG_ADDR_TXEXECESSDEF , "TXEXECESSDEF"}, {OGMA_GMAC_REG_ADDR_TXPAUSEFRAMES , "TXPAUSEFRAMES"}, {OGMA_GMAC_REG_ADDR_TXVLANFRAMES_G , "TXVLANFRAMES_G"}, {OGMA_GMAC_REG_ADDR_RXFRAMECOUNT_GB , "RXFRAMECOUNT_GB"}, {OGMA_GMAC_REG_ADDR_RXOCTETCOUNT_GB , "RXOCTETCOUNT_GB"}, {OGMA_GMAC_REG_ADDR_RXOCTETCOUNT_G , "RXOCTETCOUNT_G"}, {OGMA_GMAC_REG_ADDR_RXBROADCASTFRAMES_G , "RXBROADCASTFRAMES_G"}, {OGMA_GMAC_REG_ADDR_RXMULTICASTFRAMES_G , "RXMULTICASTFRAMES_G"}, {OGMA_GMAC_REG_ADDR_RXCRCERROR , "RXCRCERROR"}, {OGMA_GMAC_REG_ADDR_RXALLIGNMENTERROR , "RXALLIGNMENTERROR"}, {OGMA_GMAC_REG_ADDR_RXRUNTERROR , "RXRUNTERROR"}, {OGMA_GMAC_REG_ADDR_RXJABBERERROR , "RXJABBERERROR"}, {OGMA_GMAC_REG_ADDR_RXUNDERSIZE_G , "RXUNDERSIZE_G"}, {OGMA_GMAC_REG_ADDR_RXOVERSIZE_G , "RXOVERSIZE_G"}, {OGMA_GMAC_REG_ADDR_RX64OCTETS_GB , "RX64OCTETS_GB"}, {OGMA_GMAC_REG_ADDR_RX65TO127OCTETS_GB , "RX65TO127OCTETS_GB"}, {OGMA_GMAC_REG_ADDR_RX128TO255OCTETS_GB , "RX128TO255OCTETS_GB"}, {OGMA_GMAC_REG_ADDR_RX256TO511OCTETS_GB , "RX256TO511OCTETS_GB"}, {OGMA_GMAC_REG_ADDR_RX512TO1023OCTETS_GB, "RX512TO1023OCTETS_GB"}, {OGMA_GMAC_REG_ADDR_RX1024TOMAXOCTETS_GB, "RX1024TOMAXOCTETS_GB"}, {OGMA_GMAC_REG_ADDR_RXUNICASTFRAMES_G , "RXUNICASTFRAMES_G"}, {OGMA_GMAC_REG_ADDR_RXLENGTHERROR , "RXLENGTHERROR"}, {OGMA_GMAC_REG_ADDR_RXOUTOFRANGETYPE , "RXOUTOFRANGETYPE"}, {OGMA_GMAC_REG_ADDR_RXPAUSEFRAMES , "RXPAUSEFRAMES"}, {OGMA_GMAC_REG_ADDR_RXFIFOOVERFLOW , "RXFIFOOVERFLOW"}, {OGMA_GMAC_REG_ADDR_RXVLANFRAMES_GB , "RXVLANFRAMES_GB"}, {OGMA_GMAC_REG_ADDR_RXWATCHDOGERROR , "RXWATCHDOGERROR"}, {OGMA_GMAC_REG_ADDR_MMC_IPC_INTR_MASK_RX, "MMC_IPC_INTR_MASK_RX"}, {OGMA_GMAC_REG_ADDR_MMC_IPC_INTR_RX , "MMC_IPC_INTR_RX"}, {OGMA_GMAC_REG_ADDR_RXIPV4_GD_FRMS , "RXIPV4_GD_FRMS"}, {OGMA_GMAC_REG_ADDR_RXIPV4_HDRERR_FRMS , "RXIPV4_HDRERR_FRMS"}, {OGMA_GMAC_REG_ADDR_RXIPV4_NOPAY_FRMS , "RXIPV4_NOPAY_FRMS"}, {OGMA_GMAC_REG_ADDR_RXIPV4_FRAG_FRMS , "RXIPV4_FRAG_FRMS"}, {OGMA_GMAC_REG_ADDR_RXIPV4_UDSBL_FRMS , "RXIPV4_UDSBL_FRMS"}, {OGMA_GMAC_REG_ADDR_RXIPV6_GD_FRMS , "RXIPV6_GD_FRMS"}, {OGMA_GMAC_REG_ADDR_RXIPV6_HDRERR_FRMS , "RXIPV6_HDRERR_FRMS"}, {OGMA_GMAC_REG_ADDR_RXIPV6_NOPAY_FRMS , "RXIPV6_NOPAY_FRMS"}, {OGMA_GMAC_REG_ADDR_RXUDP_GD_FRMS , "RXUDP_GD_FRMS"}, {OGMA_GMAC_REG_ADDR_RXUDP_ERR_FRMS , "RXUDP_ERR_FRMS"}, {OGMA_GMAC_REG_ADDR_RXTCP_GD_FRMS , "RXTCP_GD_FRMS"}, {OGMA_GMAC_REG_ADDR_RXTCP_ERR_FRMS , "RXTCP_ERR_FRMS"}, {OGMA_GMAC_REG_ADDR_RXICMP_GD_FRMS , "RXICMP_GD_FRMS"}, {OGMA_GMAC_REG_ADDR_RXICMP_ERR_FRMS , "RXICMP_ERR_FRMS"}, {OGMA_GMAC_REG_ADDR_RXIPV4_GD_OCTETS , "RXIPV4_GD_OCTETS"}, {OGMA_GMAC_REG_ADDR_RXIPV4_HDRERR_OCTETS, "RXIPV4_HDRERR_OCTETS"}, {OGMA_GMAC_REG_ADDR_RXIPV4_NOPAY_OCTETS , "RXIPV4_NOPAY_OCTETS"}, {OGMA_GMAC_REG_ADDR_RXIPV4_FRAG_OCTETS , "RXIPV4_FRAG_OCTETS"}, {OGMA_GMAC_REG_ADDR_RXIPV4_UDSBL_OCTETS , "RXIPV4_UDSBL_OCTETS"}, {OGMA_GMAC_REG_ADDR_RXIPV6_GD_OCTETS , "RXIPV6_GD_OCTETS"}, {OGMA_GMAC_REG_ADDR_RXIPV6_HDRERR_OCTETS, "RXIPV6_HDRERR_OCTETS"}, {OGMA_GMAC_REG_ADDR_RXIPV6_NOPAY_OCTETS , "RXIPV6_NOPAY_OCTETS"}, {OGMA_GMAC_REG_ADDR_RXUDP_GD_OCTETS , "RXUDP_GD_OCTETS"}, {OGMA_GMAC_REG_ADDR_RXUDP_ERR_OCTETS , "RXUDP_ERR_OCTETS"}, {OGMA_GMAC_REG_ADDR_RXTCP_GD_OCTETS , "RXTCP_GD_OCTETS"}, {OGMA_GMAC_REG_ADDR_RXTCP_ERR_OCTETS , "RXTCP_ERR_OCTETS"}, {OGMA_GMAC_REG_ADDR_RXICMP_GD_OCTETS , "RXICMP_GD_OCTETS"}, {OGMA_GMAC_REG_ADDR_RXICMP_ERR_OCTETS , "RXICMP_ERR_OCTETS"} }; #endif /* ( defined(OGMA_CONFIG_USE_READ_GMAC_STAT) || defined(OGMA_CONFIG_USE_DUMP_GMAC_STAT) ) */ #ifdef OGMA_CONFIG_USE_DUMP_GMAC_STAT void ogma_dump_gmac_stat (ogma_ctrl_t *ctrl_p) { ogma_uint i; pfdep_print(PFDEP_DEBUG_LEVEL_NOTICE, "Dumping GMAC statistics registers(MMC registers):\n"); for (i = 0; i < sizeof(ogma_gmac_mmc_reg_info)/sizeof(ogma_gmac_mmc_reg_info[0]); i++) { pfdep_print(PFDEP_DEBUG_LEVEL_NOTICE, " %s => 0x%08x\n", ogma_gmac_mmc_reg_info[i].name_p, ( unsigned long)ogma_get_mac_reg(ctrl_p, ogma_gmac_mmc_reg_info[i].addr)); } /* Reset all counters. */ ogma_set_mac_reg(ctrl_p, OGMA_GMAC_REG_ADDR_MMC_CNTL, 1); } #endif /* OGMA_CONFIG_USE_DUMP_GMAC_STAT */ ogma_err_t ogma_get_gmac_status ( ogma_handle_t ogma_handle, ogma_bool *valid_flag_p, ogma_gmac_mode_t *gmac_mode_p, ogma_bool *rx_running_flag_p, ogma_bool *tx_running_flag_p ) { ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if ( valid_flag_p == NULL) { return OGMA_ERR_PARAM; } if ( ( ctrl_p == NULL) || ( gmac_mode_p == NULL) || ( rx_running_flag_p == NULL) || ( tx_running_flag_p == NULL) ) { *valid_flag_p = OGMA_FALSE; return OGMA_ERR_PARAM; } if ( !ctrl_p->param.use_gmac_flag) { *valid_flag_p = OGMA_FALSE; return OGMA_ERR_NOTAVAIL; } *valid_flag_p = ctrl_p->gmac_mode_valid_flag; *rx_running_flag_p = ctrl_p->gmac_rx_running_flag; *tx_running_flag_p = ctrl_p->gmac_tx_running_flag; pfdep_memcpy( ( void *)gmac_mode_p, ( const void *)&ctrl_p->gmac_mode, sizeof( ogma_gmac_mode_t) ); return OGMA_ERR_OK; } static void ogma_set_phy_target_mmd_reg_addr ( ogma_ctrl_t *ctrl_p, ogma_uint8 dev_addr, ogma_uint16 reg_addr ) { ogma_uint32 cmd; /* set MMD ADDR */ cmd = ( ogma_uint32)dev_addr; /*set command to MMD access control register */ ogma_set_phy_reg_sub( ctrl_p, OGMA_PHY_REG_ADDR_MMD_AC, cmd); /* set MMD access address data register Write reg_addr */ ogma_set_phy_reg_sub( ctrl_p, OGMA_PHY_REG_ADDR_MMD_AAD, reg_addr); /* write value to MMD ADDR */ cmd = ( (1U << 14) | dev_addr); /* set command to MMD access control register */ ogma_set_phy_reg_sub( ctrl_p, OGMA_PHY_REG_ADDR_MMD_AC, cmd); } static void ogma_set_phy_mmd_reg_sub ( ogma_ctrl_t *ctrl_p, ogma_uint8 dev_addr, ogma_uint16 reg_addr, ogma_uint16 value ) { /* set target mmd reg_addr */ ogma_set_phy_target_mmd_reg_addr( ctrl_p, dev_addr, reg_addr); /* Write value to MMD access address data register */ ogma_set_phy_reg_sub( ctrl_p, OGMA_PHY_REG_ADDR_MMD_AAD, value); } static ogma_uint16 ogma_get_phy_mmd_reg_sub ( ogma_ctrl_t *ctrl_p, ogma_uint8 dev_addr, ogma_uint16 reg_addr ) { /* set target mmd reg_addr */ ogma_set_phy_target_mmd_reg_addr( ctrl_p, dev_addr, reg_addr); /* Read value for MMD access address data register */ return ogma_get_phy_reg_sub( ctrl_p, OGMA_PHY_REG_ADDR_MMD_AAD); } ogma_err_t ogma_set_gmac_lpictrl_reg ( ogma_handle_t ogma_handle, ogma_uint32 value ) { ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if ( ctrl_p == NULL) { return OGMA_ERR_PARAM; } if ( !ctrl_p->param.use_gmac_flag) { return OGMA_ERR_NOTAVAIL; } /* set value tp LSIPCR Register */ ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_LPICSR, value); return OGMA_ERR_OK; } ogma_err_t ogma_get_gmac_lpictrl_reg ( ogma_handle_t ogma_handle, ogma_uint32 *value_p ) { ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if ( ( ctrl_p == NULL) || ( value_p == NULL) ){ return OGMA_ERR_PARAM; } if ( !ctrl_p->param.use_gmac_flag) { return OGMA_ERR_NOTAVAIL; } /* Read LSIPCR Register */ *value_p = ogma_get_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_LPICSR); return OGMA_ERR_OK; } ogma_err_t ogma_set_gmac_lpitimer_reg ( ogma_handle_t ogma_handle, ogma_uint16 ls_timer_ms, ogma_uint16 tw_timer_ms ) { ogma_uint32 value; ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if ( ctrl_p == NULL) { return OGMA_ERR_PARAM; } if ( ls_timer_ms > 1024U) { return OGMA_ERR_RANGE; } if ( !ctrl_p->param.use_gmac_flag) { return OGMA_ERR_NOTAVAIL; } /* make LPICTR value*/ value = ( ( ( ogma_uint32)ls_timer_ms << OGMA_GMAC_LPITCR_REG_LIT) | ( tw_timer_ms << OGMA_GMAC_LPITCR_REG_TWT) ); /* Write timer value to LSIPCR Register */ ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_LPITCR, value); return OGMA_ERR_OK; } ogma_err_t ogma_get_gmac_lpitimer_reg ( ogma_handle_t ogma_handle, ogma_uint16 *ls_timer_ms_p, ogma_uint16 *tw_timer_ms_p ) { ogma_uint32 value; ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if ( ( ctrl_p == NULL) || ( ls_timer_ms_p == NULL) || ( tw_timer_ms_p == NULL) ) { return OGMA_ERR_PARAM; } if ( !ctrl_p->param.use_gmac_flag) { return OGMA_ERR_NOTAVAIL; } /* Read timer value for LSIPCR Register */ value = ogma_get_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_LPITCR); /* make ls_timer_ms value*/ *ls_timer_ms_p = ( ogma_uint16)( ( value >> OGMA_GMAC_LPITCR_REG_LIT) & OGMA_GMAC_LPITCR_REG_MASK_LIT); /* make tw_timer_ms value*/ *tw_timer_ms_p = ( ogma_uint16)( ( value >> OGMA_GMAC_LPITCR_REG_TWT) & OGMA_GMAC_LPITCR_REG_MASK_TWT); return OGMA_ERR_OK; } void ogma_set_phy_mmd_reg ( ogma_handle_t ogma_handle, ogma_uint8 dev_addr, ogma_uint16 reg_addr, ogma_uint16 value ) { ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if ( ctrl_p == NULL) { return; } if ( dev_addr > 31U) { return; } if ( !ctrl_p->param.use_gmac_flag) { return; } ogma_set_phy_mmd_reg_sub ( ctrl_p, dev_addr, reg_addr, value); return; } ogma_uint16 ogma_get_phy_mmd_reg ( ogma_handle_t ogma_handle, ogma_uint8 dev_addr, ogma_uint16 reg_addr ) { ogma_uint16 value; ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if ( ctrl_p == NULL) { return 0; } if ( dev_addr > 31U) { return 0; } if ( !ctrl_p->param.use_gmac_flag) { return 0; } value = ogma_get_phy_mmd_reg_sub ( ctrl_p, dev_addr, reg_addr); return value; } ogma_err_t ogma_get_phy_link_status ( ogma_handle_t ogma_handle, ogma_phy_link_status_t *phy_link_status_p ) { ogma_uint32 value, tmp, exp; ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if ( ( ctrl_p == NULL) || ( phy_link_status_p == NULL) ){ return OGMA_ERR_PARAM; } if ( !ctrl_p->param.use_gmac_flag) { return OGMA_ERR_NOTAVAIL; } pfdep_memset( phy_link_status_p, 0, sizeof( ogma_phy_link_status_t) ); /* Read PHY CONTROL Register */ tmp = ogma_get_phy_reg_sub( ctrl_p, OGMA_PHY_REG_ADDR_CONTROL); /* Read PHY STATUS Register */ value = ogma_get_phy_reg_sub( ctrl_p, OGMA_PHY_REG_ADDR_STATUS); /* check latched_link_down_flag */ if ( ( value & ( 1U << OGMA_PHY_STATUS_REG_LINK_STATUS) ) == 0) { phy_link_status_p->latched_link_down_flag = OGMA_TRUE; /* Read PHY STATUS Register */ value = ogma_get_phy_reg_sub( ctrl_p, OGMA_PHY_REG_ADDR_STATUS); } pfdep_print( PFDEP_DEBUG_LEVEL_DEBUG_MORE_DETAILED, "CONTROL Register value %08x\n", tmp); pfdep_print( PFDEP_DEBUG_LEVEL_DEBUG_MORE_DETAILED, "PHY STATUS register value %08x\n", value); /* Check Current Link Status */ if ( ( value & ( 1U << OGMA_PHY_STATUS_REG_LINK_STATUS) ) != 0 ) { phy_link_status_p->up_flag = OGMA_TRUE; } /* check Auto-Negotiation Enable */ if ( ( ( tmp & ( 1U << OGMA_PHY_CONTROL_REG_AUTO_NEGO_ENABLE) ) != 0) && ( ( value & ( 1U << OGMA_PHY_STATUS_REG_AUTO_NEGO_ABILITY) ) != 0) ) { phy_link_status_p->auto_nego_enable_flag = OGMA_TRUE; } /* Check Current Autonegotiation Complete Status */ if ( phy_link_status_p->up_flag && phy_link_status_p->auto_nego_enable_flag && ( ( value & ( 1U << OGMA_PHY_STATUS_REG_AUTO_NEGO_COMP) ) != 0) ) { phy_link_status_p->auto_nego_complete_flag = OGMA_TRUE; } /* start Check Current Link Speed */ if ( phy_link_status_p->up_flag) { if ( phy_link_status_p->auto_nego_enable_flag == OGMA_FALSE) { /* Speed check */ if ( ( ( tmp & ( 1U << OGMA_PHY_CONTROL_REG_SPEED_SELECTION_LSB) ) == 0) && ( ( tmp & ( 1U << OGMA_PHY_CONTROL_REG_SPEED_SELECTION_MSB) ) != 0) ) { phy_link_status_p->link_speed = OGMA_PHY_LINK_SPEED_1G; } else if ( ( ( tmp & ( 1U << OGMA_PHY_CONTROL_REG_SPEED_SELECTION_LSB) ) != 0) && ( ( tmp & ( 1U << OGMA_PHY_CONTROL_REG_SPEED_SELECTION_MSB) ) == 0) ) { phy_link_status_p->link_speed = OGMA_PHY_LINK_SPEED_100M; } else { phy_link_status_p->link_speed = OGMA_PHY_LINK_SPEED_10M; } /* Duplex check */ if ( ( tmp & ( 1U << OGMA_PHY_CONTROL_REG_DUPLEX_MODE) ) == 0) { phy_link_status_p->half_duplex_flag = OGMA_TRUE; } } else if ( phy_link_status_p->auto_nego_complete_flag == OGMA_TRUE) { /* case auto_nego_enable_flag TRUE && auto_nego_complete_flag TRUE */ /* Read MASTER-SLAVE Control Register */ value = ogma_get_phy_reg_sub( ctrl_p, OGMA_PHY_REG_ADDR_MASTER_SLAVE_CONTROL); /* Read MASTER-SLAVE Status Register */ tmp = ogma_get_phy_reg_sub( ctrl_p, OGMA_PHY_REG_ADDR_MASTER_SLAVE_STATUS); /* Check Current Link Speed */ if ( ( ( value & ( 1U << OGMA_PHY_MSC_REG_1000BASE_FULL) ) != 0) && ( ( tmp & ( 1U << OGMA_PHY_MSS_REG_LP_1000BASE_FULL) ) != 0) ) { phy_link_status_p->link_speed = OGMA_PHY_LINK_SPEED_1G; } else if ( ( ( value & ( 1U << OGMA_PHY_MSC_REG_1000BASE_HALF) ) != 0) && ( ( tmp & ( 1U << OGMA_PHY_MSS_REG_LP_1000BASE_HALF) ) != 0) ) { phy_link_status_p->link_speed = OGMA_PHY_LINK_SPEED_1G; phy_link_status_p->half_duplex_flag = OGMA_TRUE; } else { /* Read Auto-Negotiation Advertisement register */ value = ogma_get_phy_reg_sub( ctrl_p, OGMA_PHY_REG_ADDR_AUTO_NEGO_ABILTY); /* Read Auto-Negotiation Link Partner Base Page Ability register */ tmp = ogma_get_phy_reg_sub( ctrl_p, OGMA_PHY_REG_ADDR_AUTO_NEGO_LINK_PATNER_ABILTY); value = ( ( ( value & tmp) >> OGMA_PHY_ANA_REG_TAF) & OGMA_PHY_ANA_REG_TAF_MASK); pfdep_print( PFDEP_DEBUG_LEVEL_DEBUG_MORE_DETAILED, "TAF value %08x\n", value); if ( value & OGMA_PHY_TAF_REG_100BASE_FULL) { /* 100M full */ phy_link_status_p->link_speed = OGMA_PHY_LINK_SPEED_100M; } else if ( value & OGMA_PHY_TAF_REG_100BASE_HALF) { /* 100M half */ phy_link_status_p->link_speed = OGMA_PHY_LINK_SPEED_100M; phy_link_status_p->half_duplex_flag = OGMA_TRUE; } else if ( value & OGMA_PHY_TAF_REG_10BASE_FULL) { /* 10M full */ phy_link_status_p->link_speed = OGMA_PHY_LINK_SPEED_10M; } else { /* value = OGMA_PHY_TAF_REG_10BASE_HALF 10M Half */ phy_link_status_p->link_speed = OGMA_PHY_LINK_SPEED_10M; phy_link_status_p->half_duplex_flag = OGMA_TRUE; } } } } /* End Check Current Link Speed */ /* Check LPI Capable */ if ( phy_link_status_p->up_flag && phy_link_status_p->auto_nego_complete_flag && phy_link_status_p->link_speed != OGMA_PHY_LINK_SPEED_10M && phy_link_status_p->half_duplex_flag == OGMA_FALSE && ctrl_p->param.gmac_config.phy_interface != OGMA_PHY_INTERFACE_RMII) { /* Read EEE advertisement register */ value = ogma_get_phy_mmd_reg_sub( ctrl_p, OGMA_PHY_DEV_ADDR_AUTO_NEGO, OGMA_PHY_AUTO_NEGO_REG_ADDR_EEE_ADVERTISE); /* Read EEE link partner ability register */ tmp = ogma_get_phy_mmd_reg_sub( ctrl_p, OGMA_PHY_DEV_ADDR_AUTO_NEGO, OGMA_PHY_AUTO_NEGO_REG_ADDR_EEE_LP_ABILITY); exp = ( ( phy_link_status_p->link_speed == OGMA_PHY_LINK_SPEED_1G) ? OGMA_PHY_AUTO_NEGO_1000BASE_EEE: OGMA_PHY_AUTO_NEGO_100BASE_EEE); /* Check EEE Advertise and EEE LP Ability */ if ( ( value & tmp & exp) != 0 ) { phy_link_status_p->lpi_capable_flag = OGMA_TRUE; } pfdep_print( PFDEP_DEBUG_LEVEL_DEBUG_MORE_DETAILED, "EEE advertisement register value %08x\n", value); pfdep_print( PFDEP_DEBUG_LEVEL_DEBUG_MORE_DETAILED, "EEE link partner ability register value %08x\n", tmp); pfdep_print( PFDEP_DEBUG_LEVEL_DEBUG_MORE_DETAILED, "EEE LPI EXP value %08x\n", exp); } pfdep_print( PFDEP_DEBUG_LEVEL_DEBUG_MORE_DETAILED, "phy_link_status_p->latched_link_down_flag %u\n", phy_link_status_p->latched_link_down_flag); pfdep_print( PFDEP_DEBUG_LEVEL_DEBUG_MORE_DETAILED, "phy_link_status_p->up_flag %u\n", phy_link_status_p->up_flag); pfdep_print( PFDEP_DEBUG_LEVEL_DEBUG_MORE_DETAILED, "phy_link_status_p->auto_nego_enable_flag %u\n", phy_link_status_p->auto_nego_enable_flag); pfdep_print( PFDEP_DEBUG_LEVEL_DEBUG_MORE_DETAILED, "phy_link_status_p->auto_nego_complete_flag %u\n", phy_link_status_p->auto_nego_complete_flag); pfdep_print( PFDEP_DEBUG_LEVEL_DEBUG_MORE_DETAILED, "phy_link_status_p->link_speed %u\n", phy_link_status_p->link_speed); pfdep_print( PFDEP_DEBUG_LEVEL_DEBUG_MORE_DETAILED, "phy_link_status_p->lpi_capable_flag %u\n", phy_link_status_p->lpi_capable_flag); return OGMA_ERR_OK; } ogma_gmac_int_sbd_regs_t ogma_get_gmac_int_sbd_irq_enable ( ogma_handle_t ogma_handle ) { ogma_gmac_int_sbd_regs_t gmac_int_sbd_regs = {0}; ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if ( ctrl_p == NULL) { return gmac_int_sbd_regs; } if ( !ctrl_p->param.use_gmac_flag) { return gmac_int_sbd_regs; } /* Read IER register */ gmac_int_sbd_regs.base = ogma_get_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_IER); /* Read IMR register */ gmac_int_sbd_regs.extended = ( ( ~( ogma_get_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_IMR) ) ) & OGMA_GMAC_INT_SBD_IRQ_ISR_ALL); return gmac_int_sbd_regs; } ogma_gmac_int_sbd_regs_t ogma_get_gmac_int_sbd_irq_status_non_clear ( ogma_handle_t ogma_handle, ogma_bool mask_flag ) { ogma_gmac_int_sbd_regs_t gmac_int_sbd_regs = {0}; ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if ( ctrl_p == NULL) { return gmac_int_sbd_regs; } if ( !ctrl_p->param.use_gmac_flag) { return gmac_int_sbd_regs; } /* Read SR register */ gmac_int_sbd_regs.base = ogma_get_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_SR); /* Read ISR register */ gmac_int_sbd_regs.extended = ogma_get_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_ISR); if ( mask_flag) { /* Read IER register */ gmac_int_sbd_regs.base &= ( ogma_get_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_IER) | ( ~OGMA_GMAC_INT_SBD_IRQ_IER_ALL) ); /* Read IMR register */ gmac_int_sbd_regs.extended &= ( ( ~( ogma_get_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_IMR) ) ) & OGMA_GMAC_INT_SBD_IRQ_ISR_ALL); } return gmac_int_sbd_regs; } ogma_err_t ogma_clear_gmac_int_sbd_irq_status ( ogma_handle_t ogma_handle, ogma_gmac_int_sbd_regs_t int_sbd_regs ) { ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if ( ctrl_p == NULL) { return OGMA_ERR_PARAM; } if ( !ctrl_p->param.use_gmac_flag) { return OGMA_ERR_NOTAVAIL; } /* Write Clear SR register */ ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_SR, ( int_sbd_regs.base & OGMA_GMAC_INT_SBD_IRQ_SR_WC_ALL) ); return OGMA_ERR_OK; } ogma_err_t ogma_enable_gmac_int_sbd_irq ( ogma_handle_t ogma_handle, ogma_gmac_int_sbd_regs_t int_sbd_regs ) { ogma_uint32 value; ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if ( ctrl_p == NULL) { return OGMA_ERR_PARAM; } if ( !ctrl_p->param.use_gmac_flag) { return OGMA_ERR_NOTAVAIL; } /* Read IER register for No Change Value Keep */ value = ogma_get_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_IER); /* Write IER register */ ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_IER, ( value | ( int_sbd_regs.base & OGMA_GMAC_INT_SBD_IRQ_IER_ALL) ) ); /* Read IMR register for No Change Value Keep */ value = ogma_get_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_IMR); /* Write IMR register */ ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_IMR, ( value & ( ~( int_sbd_regs.extended & OGMA_GMAC_INT_SBD_IRQ_ISR_ALL) ) ) ); return OGMA_ERR_OK; } ogma_err_t ogma_disable_gmac_int_sbd_irq ( ogma_handle_t ogma_handle, ogma_gmac_int_sbd_regs_t int_sbd_regs ) { ogma_uint32 value; ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if ( ctrl_p == NULL) { return OGMA_ERR_PARAM; } if ( !ctrl_p->param.use_gmac_flag) { return OGMA_ERR_NOTAVAIL; } /* Read IER register for No Change Value Keep */ value = ogma_get_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_IER); /* Write IER register */ ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_IER, ( value & ( ~(int_sbd_regs.base) ) ) ); /* Read IMR register for No Change Value Keep */ value = ogma_get_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_IMR); /* Write IMR register */ ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_IMR, ( value | ( int_sbd_regs.extended & OGMA_GMAC_INT_SBD_IRQ_ISR_ALL) ) ); return OGMA_ERR_OK; } ogma_err_t ogma_get_gmac_rgmii_status_reg ( ogma_handle_t ogma_handle, ogma_uint32 *value_p ) { ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if ( ( ctrl_p == NULL) || ( value_p == NULL) ){ return OGMA_ERR_PARAM; } if ( !ctrl_p->param.use_gmac_flag) { return OGMA_ERR_NOTAVAIL; } /* Read RGMII Status Register */ *value_p = ogma_get_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_RSR); return OGMA_ERR_OK; } #ifdef OGMA_CONFIG_USE_READ_GMAC_STAT ogma_err_t ogma_read_gmac_stat ( ogma_handle_t ogma_handle, ogma_uint32 *value_p, ogma_bool reset_flag ) { ogma_uint i; ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if ( ( ctrl_p == NULL) || ( value_p == NULL) ) { return OGMA_ERR_PARAM; } for ( i = 0; i < sizeof(ogma_gmac_mmc_reg_info)/sizeof(ogma_gmac_mmc_reg_info[0] ); i++) { value_p[i] = ogma_get_mac_reg(ctrl_p, ogma_gmac_mmc_reg_info[i].addr); } if ( reset_flag) { /* Reset all counters. */ ogma_set_mac_reg(ctrl_p, OGMA_GMAC_REG_ADDR_MMC_CNTL, 1); } return OGMA_ERR_OK; } #endif /* OGMA_CONFIG_USE_READ_GMAC_STAT */ ogma_err_t ogma_reset_gmac_stat ( ogma_handle_t ogma_handle ) { ogma_ctrl_t *ctrl_p = (ogma_ctrl_t *)ogma_handle; if ( ctrl_p == NULL) { return OGMA_ERR_PARAM; } /* Reset all counters. */ ogma_set_mac_reg(ctrl_p, OGMA_GMAC_REG_ADDR_MMC_CNTL, 1); return OGMA_ERR_OK; } ogma_err_t ogma_softreset_gmac ( ogma_ctrl_t *ctrl_p ) { ogma_uint32 value; pfdep_err_t pfdep_err; /* F_GMAC4MT soft reset*/ ogma_set_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_BMR, OGMA_GMAC_BMR_REG_RESET); /* Wait soft reset */ pfdep_err = pfdep_msleep( 1); if ( pfdep_err == PFDEP_ERR_INTERRUPT) { pfdep_print( PFDEP_DEBUG_LEVEL_FATAL, "Wait for BMR soft reset error.\n"); return OGMA_ERR_INTERRUPT; } /* Read F_GMAC4MT BMR */ value = ogma_get_mac_reg( ctrl_p, OGMA_GMAC_REG_ADDR_BMR); /* check software reset result*/ if ( value & OGMA_GMAC_BMR_REG_SWR) { return OGMA_ERR_AGAIN; } return OGMA_ERR_OK; }