/* CHIP : Arsenal5 */ cs_status arn5_dev_print_stats(cs_uint8 dev_id) /* INPUTS : o Device Id */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Prints statistics for the device. */ /* It prints the Statistics of all the blocks that are registered and */ /* are active in the current mode. */ /* $rtn_hdr_end */ /************************************************************************/ { cs_uint32 error = 0 ; if (ARN5_IS_DEVICE_VALID(dev_id, &error) != TRUE) { CS_HNDL_ERROR(dev_id, error, NULL) ; return (CS_ERROR) ; } CS_PRINT("\n") ; if ( arn5_drvr_is_esc_code_enbld() ) { CS_PRINT("\033[7m Device-%d STATISTICS :\033[m\n", dev_id) ; } else { CS_PRINT(" Device-%d STATISTICS :\n", dev_id) ; } if ( ARN5_STATS_IS_BLK_REGISTERED((cs_uint16)dev_id, ARN5_DEVICE, ARN5_ID_HOST_IF) ) { arn5_dev_print_blk_stats(dev_id, ARN5_ID_HOST_IF) ; } return (CS_OK) ; }
/***************************************** * Print Port Configuration Summary * *****************************************/ static void arn5_port_dump_cfg_summ(cs_uint16 port_id, arn5_port_summ_t * pSumm) { if (pSumm == NULL) { CS_PRINT("Port-0x%x %s() ERROR: pSumm is NULL\n", port_id, __FUNCTION__) ; return ; } CS_PRINT( "==============================================================\n" ) ; if ( arn5_drvr_is_esc_code_enbld() ) { CS_PRINT("\033[4m") ; /* underline */ CS_PRINT("\t\t Arsenal5 Port-0x%x Configuration Summary\n\n", port_id) ; CS_PRINT("\033[m") ; /* back to normal printing */ } else { CS_PRINT("\t\t Arsenal5 Port-0x%x Configuration Summary\n\n", port_id) ; } CS_PRINT("Line Rate = %s, L2 Protocol = %s\n", ARN5_GET_LINE_RATE_NAME(pSumm->line_rate), ARN5_GET_L2_PROT_NAME(pSumm->l2_prot)) ; CS_PRINT( "==============================================================\n" ) ; }
/* CHIP : Arsenal5 */ cs_status arn5_dev_dump_running_cfg(cs_uint8 dev_id) /* INPUTS : o Device Id */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Retrieves and prints the current run-time hardware */ /* configuration for the specified device. */ /* $rtn_hdr_end */ /****************************************************************/ { arn5_dev_runcfg_t * pRunCfg = NULL ; cs_uint32 err_code ; cs_status status = CS_OK ; if ( !(ARN5_IS_DEVICE_VALID(dev_id, &err_code)) ) { CS_HNDL_ERROR(dev_id, err_code, NULL) ; return(CS_ERROR) ; } pRunCfg = (arn5_dev_runcfg_t *) CS_MALLOC( sizeof(arn5_dev_runcfg_t) ) ; if (pRunCfg == NULL) { CS_PRINT("ARN5 dev-%d ERROR: pRunCfg is NULL\n", dev_id) ; return (CS_ERROR) ; } if ( arn5_dev_get_running_cfg(dev_id, pRunCfg) != CS_OK ) { status = CS_ERROR ; goto RTN_EXIT ; } arn5_print_drvr_ver() ; /* first print driver rel info */ CS_PRINT("\n") ; CS_PRINT("\t\t *************************************\n") ; CS_PRINT("\t\t * DEVICE-%02d RUNNING CONFIGURATION *\n", dev_id) ; CS_PRINT("\t\t *************************************\n") ; CS_PRINT("Chip JTAG-Id= 0x%08x\n", pRunCfg->jtag_id) ; arn5_dev_dump_cfg_summ(dev_id, &pRunCfg->summ) ; CS_PRINT("\t GPIO alarm status pins = 0x%02x, output pins = 0x%04x,\n", pRunCfg->gpio.alm_status_map, pRunCfg->gpio.io_map) ; CS_PRINT("\t\t\t\t output values = 0x%04x\n", pRunCfg->gpio.output_values) ; CS_PRINT("=================================================\n") ; CS_PRINT("\t\t SPI Block\n\n") ; if ( arn5_spi_dev_dump_running_cfg(dev_id, pRunCfg) != CS_OK ) { status = CS_ERROR ; goto RTN_EXIT ; } RTN_EXIT : if (pRunCfg) CS_FREE(pRunCfg) ; return(status) ; }
/***************************************** * Print Device Configuration Summary * *****************************************/ static void arn5_dev_dump_cfg_summ(cs_uint8 dev_id, arn5_dev_summ_t * pSumm) { if (pSumm == NULL) { CS_PRINT("dev-%d %s() ERROR: pSumm is NULL!\n", dev_id, __FUNCTION__) ; return ; } CS_PRINT( "==============================================================\n" ) ; if ( arn5_drvr_is_esc_code_enbld() ) { CS_PRINT("\033[4m") ; /* underline */ CS_PRINT("\t\t Arsenal5 Device-%d Configuration Summary\n\n", dev_id) ; CS_PRINT("\033[m") ; /* back to normal printing */ } else { CS_PRINT("\t\t Arsenal5 Device-%d Configuration Summary\n\n", dev_id) ; } CS_PRINT("Host Interface = %s\n", ARN5_GET_HOST_IF_NAME(pSumm->host_if)) ; CS_PRINT( "==============================================================\n" ) ; }
uint32_t objToBin(const char* _filePath , bx::WriterSeekerI* _writer , uint32_t _packUv , uint32_t _packNormal , bool _ccw , bool _flipV , bool _hasTangent , float _scale ) { FILE* file = fopen(_filePath, "rb"); if (NULL == file) { CS_PRINT("Unable to open input file '%s'.", _filePath); return 0; } uint32_t size = (uint32_t)dm::fsize(file); char* data = new char[size+1]; size = (uint32_t)fread(data, 1, size, file); data[size] = '\0'; fclose(file); const uint32_t dataSize = objToBin((uint8_t*)data, _writer, _packUv, _packNormal, _ccw, _flipV, _hasTangent, _scale); delete [] data; return dataSize; }
/********************************************************************* * Create Port-Id(or Port Handle) * * Port-Id is created by OR'ing (dev_id << 8) and port-num. * * On successful assignment of the Port-Id, memory for the Port * * Control Block(PCB) will be dynamically allocated and returned * * to the user. * *********************************************************************/ cs_status arn5_dev_create_port_id(cs_uint8 dev_id, arn5_port_summ_t * pSumm, cs_uint16 * p_port_id, arn5_port_cb_t ** p_ppcb, cs_uint8 slice_num) { arn5_dev_cb_t * pdevcb = ARN5_DEV_ID_TO_DEVCB_PTR(dev_id) ; if (pdevcb == NULL || p_port_id == NULL || p_ppcb == NULL) { return (CS_ERROR) ; } if (slice_num > ARN5_MAX_NUM_PORTS) { return (CS_ERROR) ; } *p_port_id = ARN5_INVALID_PORT_ID ; *p_ppcb = NULL ; if (pdevcb->ppcb[slice_num]) { /* check if it is already in-use */ CS_PRINT("Dev-%d ERROR: slice-%d already in use!\n", dev_id, slice_num) ; return (CS_ERROR) ; } *p_ppcb = (arn5_port_cb_t *) CS_MALLOC( sizeof(arn5_port_cb_t) ) ; if (*p_ppcb == NULL) { CS_HNDL_ERROR(dev_id, EARN5_DEV_MALLOC_FAILED, NULL) ; return (CS_ERROR) ; } pdevcb->ppcb[slice_num] = *p_ppcb ; *p_port_id = ( (dev_id << 8) | slice_num ) ; return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_dev_print_sect_stats(cs_uint8 dev_id, arn5_module_id_t mod_id, cs_uint16 sect_id) /* INPUTS : o Device Id */ /* o Module ID */ /* o Section ID */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Prints the Stats for the user specified section of the device. */ /* Stats within a block are organised as a collection of section stats. */ /* Each section is identified by mod_id and section_id combo. */ /* Refer to the individual header files for the section ID defines. */ /* */ /* The [mod_id] parameter is specified as ARN5_ID_HOST_IF only */ /* $rtn_hdr_end */ /************************************************************************/ { cs_uint32 error = 0 ; arn5_stats_sect_cb_t * sect_cb = NULL ; arn5_stats_blk_cb_t * blk_cb ; if (ARN5_IS_DEVICE_VALID(dev_id, &error) != TRUE) { CS_HNDL_ERROR(dev_id, error, NULL) ; return (CS_ERROR) ; } if (sect_id >= ARN5_STATS_MAX_SECT) { CS_HNDL_ERROR(dev_id, EARN5_DEV_RANGE_ERR, NULL) ; return (CS_ERROR) ; } blk_cb = arn5_stats_get_blk_cb((cs_uint16)dev_id, ARN5_DEVICE, mod_id) ; if (blk_cb == NULL) { CS_HNDL_ERROR(dev_id, EARN5_DEV_TBL_NULL, "%s not registered for Statistics\n", ARN5_GET_MOD_NAME(mod_id)) ; return (CS_ERROR) ; } if ((sect_cb = blk_cb->p_sect_cb[sect_id]) == NULL) { CS_HNDL_ERROR(dev_id, EARN5_DEV_TBL_NULL, "Section not registered for Statistics (%d)\n", sect_id) ; return (CS_ERROR) ; } if (sect_cb->enabled == FALSE) { CS_PRINT("STATISTICS DISABLED FOR %s section %s\n", blk_cb->blk_name, sect_cb->sect_name) ; return (CS_ERROR) ; } arn5_stats_print_sect_hdr((cs_uint16)dev_id, ARN5_DEVICE, sect_cb->sect_name) ; arn5_stats_sect_cmn_op((cs_uint16)dev_id, ARN5_DEVICE, mod_id, sect_id, sect_cb, ARN5_STATS_PRINT, CS_RX_AND_TX) ; return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_dev_clear_sect_dir_stats(cs_uint8 dev_id, arn5_module_id_t mod_id, cs_uint16 sect_id, cs_dir_t dir) /* INPUTS : o Device Id */ /* o Module ID */ /* o Section ID */ /* o CS_RX or CS_TX or CS_RX_AND_TX */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Clears the Stats for the section in user specified block's section. */ /* It clears the stats and hw register for the direction specified. */ /* Refer to the individual header files for the section ID defines. */ /* */ /* The [mod_id] parameter is specified as ARN5_ID_HOST_IF only */ /* $rtn_hdr_end */ /************************************************************************/ { cs_uint32 error = 0 ; arn5_stats_sect_cb_t * stats_sect_cb = NULL ; arn5_stats_blk_cb_t * stats_blk_cb ; if (ARN5_IS_DEVICE_VALID(dev_id, &error) != TRUE) { CS_HNDL_ERROR(dev_id, error, "\n") ; return (CS_ERROR) ; } if (sect_id >= ARN5_STATS_MAX_SECT) { CS_HNDL_ERROR(dev_id, EARN5_DEV_RANGE_ERR, NULL ) ; return (CS_ERROR) ; } stats_blk_cb = arn5_stats_get_blk_cb((cs_uint16)dev_id, ARN5_DEVICE, mod_id) ; if (stats_blk_cb == NULL) { CS_HNDL_ERROR(dev_id, EARN5_DEV_TBL_NULL, "%s not registered for Statistics\n", ARN5_GET_MOD_NAME(mod_id)) ; return (CS_ERROR) ; } if ((stats_sect_cb = stats_blk_cb->p_sect_cb[sect_id]) == NULL) { CS_HNDL_ERROR( dev_id, EARN5_DEV_TBL_NULL, "Section not registered for Statistics\n") ; return (CS_ERROR) ; } if (stats_sect_cb->enabled == FALSE) { CS_PRINT("STATISTICS DISABLED FOR %s section %s\n", stats_blk_cb->blk_name, stats_sect_cb->sect_name) ; return (CS_ERROR) ; } arn5_stats_sect_cmn_op((cs_uint16)dev_id, ARN5_DEVICE, mod_id, sect_id, stats_sect_cb, ARN5_STATS_CLEAR, dir) ; return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_dev_unregister(cs_uint8 dev_id) /* INPUTS : o Device Id */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Unregisters the device, by setting its state to init state. */ /* All port and device API's related to this device should NOT */ /* be called after this. */ /* $rtn_hdr_end */ /****************************************************************/ { cs_uint32 ii ; arn5_dev_cb_t * pdevcb ; arn5_dev_cb_t ** p_pdevcb ; cs_uint32 err_code ; if ( !(ARN5_IS_DEVICE_VALID(dev_id, &err_code)) ) { CS_HNDL_ERROR(dev_id, err_code, ":dev_id(%d)\n", dev_id) ; return (CS_ERROR) ; } p_pdevcb = &( (ARN5_GET_DEVCB_TBL())[dev_id] ) ; pdevcb = *p_pdevcb ; /* need to check if this device is registered */ if ( pdevcb == NULL)return (CS_OK) ; for (ii = 0; ii < ARN5_MAX_NUM_PORTS; ii++) { if (pdevcb->ppcb[ii]) { arn5_port_close( ARN5_DEV_PORT_NUM_TO_PORT_ID(dev_id, ii) ) ; } } #ifdef POSIX_PTHREAD if (pdevcb->dbt.irq_poll.tid) { arn5_stop_irq_polling(dev_id) ; /* cancel irq polling thread */ } #endif /* POSIX_PTHREAD */ CS_SEM_DESTROY(&pdevcb->sem.mpif); CS_SEM_DESTROY(&pdevcb->sem.host_if); arn5_stats_clean_all((cs_uint16)dev_id, ARN5_DEVICE) ; CS_FREE(pdevcb) ; *p_pdevcb = NULL ; CS_PRINT("\tARN5 device(%d) unregistered!\n", dev_id) ; #ifndef RELEASE_PLATFORM cs_lab_dev_unregister(CS_CHIP_ARSENAL5, (cs_uint16)dev_id) ; #endif return (CS_OK) ; }
/***************************************** * Verify port summary * * Check that all the parameters in the * * port configuration summary section * * are valid. * *****************************************/ static cs_status arn5_port_verify_summ(cs_uint8 dev_id, cs_uint16 port_id, arn5_port_summ_t * pSumm) { if (pSumm->l2_prot == ARN5_PORT_PROT_ETHERNET) { if (pSumm->line_rate != ARN5_PORT_RATE_GIGE) { CS_PRINT("Port-0x%x %s() ERROR: l2_prot(%d) is invalid!\n", port_id, __FUNCTION__, pSumm->l2_prot) ; return (CS_ERROR) ; } } else { if (pSumm->line_rate == ARN5_PORT_RATE_GIGE) { CS_PRINT("Port-0x%x %s() ERROR: l2_prot(%d) is invalid!\n", port_id, __FUNCTION__, pSumm->l2_prot) ; return (CS_ERROR) ; } } return (CS_OK) ; }
/***************************************** * Verify device summary * * Check that all the parameters in the * * device configuration summary section * * are valid. * *****************************************/ static cs_status arn5_dev_verify_summ(cs_uint8 dev_id, arn5_dev_summ_t * pSumm) { if ( !(CS_IN_TEST_ENV()) ) { if ( (pSumm->host_if == ARN5_HOST_IF_SPI42) && (!arn5_spi_dev_is_in_spi42_mode(dev_id))) { CS_PRINT( "dev-%d ERROR: Actual Host IF is not in SPI4.2 mode.\n", dev_id) ; return (CS_ERROR) ; } if ( (pSumm->host_if == ARN5_HOST_IF_SPI3) && (!arn5_spi_dev_is_in_spi3_mode(dev_id))) { CS_PRINT( "dev-%d ERROR: Actual Host IF is not in SPI3 mode.\n", dev_id) ; return (CS_ERROR) ; } } return (CS_OK) ; }
/************************************* * Verify port configuration * *************************************/ static cs_status arn5_port_verify_cfg(cs_uint16 port_id, arn5_port_cfg_t * pCfg) { arn5_dev_cb_t * pdevcb ; pdevcb = ARN5_PORT_ID_TO_DEVCB_PTR(port_id) ; if (pCfg->summ.line_rate == ARN5_PORT_RATE_GIGE) { if (pCfg->framer_valid) { CS_PRINT("Port-0x%x %s() ERROR: framer_valid s/b FALSE in GIGE mode!\n", port_id, __FUNCTION__) ; return (CS_ERROR) ; } } else { if (pCfg->eth_valid) { CS_PRINT("Port-0x%x %s() ERROR: eth_valid s/b FALSE in SONET/SDH mode!\n", port_id, __FUNCTION__) ; return (CS_ERROR) ; } } return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_dev_print_blk_stats(cs_uint8 dev_id, arn5_module_id_t mod_id) /* INPUTS : o Device Id */ /* o Module ID */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Prints the block's statistics for the device. */ /* */ /* The [mod_id] parameter is specified as ARN5_ID_HOST_IF only */ /* $rtn_hdr_end */ /************************************************************************/ { cs_uint32 error = 0, ii ; arn5_stats_blk_cb_t * blk_cb ; if (ARN5_IS_DEVICE_VALID(dev_id, &error) != TRUE) { CS_HNDL_ERROR(dev_id, error, NULL) ; return (CS_ERROR) ; } blk_cb = arn5_stats_get_blk_cb((cs_uint16)dev_id, ARN5_DEVICE, mod_id) ; if ( blk_cb == NULL ) { CS_HNDL_ERROR(dev_id, EARN5_DEV_TBL_NULL, "%s not registered for Statistics\n", ARN5_GET_MOD_NAME(mod_id)) ; return (CS_ERROR) ; } if (blk_cb->enabled == FALSE) { CS_PRINT("STATISTICS DISABLED FOR %s\n", blk_cb->blk_name) ; return (CS_ERROR) ; } arn5_stats_print_blk_hdr((cs_uint16)dev_id, ARN5_DEVICE, blk_cb->blk_name) ; for (ii = 0; ii < ARN5_STATS_MAX_SECT; ii++) { /* Print Section stats if valid and are enabled */ if ((blk_cb->p_sect_cb[ii]) && (blk_cb->p_sect_cb[ii]->enabled)) { arn5_dev_print_sect_stats(dev_id, mod_id, ii) ; } } return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_dump_running_cfg(cs_uint16 port_id, arn5_port_runcfg_t * pRunCfg) /* INPUTS : o Port Id */ /* o Pointer to running configuration structure */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Prints the current run-time hardware configuration for the */ /* this block. */ /* */ /* The [pRunCfg] parameter is a pointer to the running */ /* configuration data-structure allocated by the caller with */ /* the configuration data from HW already retrieved and filled */ /* in, prior to calling this API. */ /* $_hdr_end */ /**********************************************************************/ { char * pS ; arn5_lif_runcfg_t * pCfg = &pRunCfg->lif ; switch (pCfg->ref_clk) { case ARN5_LIF_REF_CLK_155 : pS = "155.52 MHz"; break; case ARN5_LIF_REF_CLK_78 : pS = "77.76 MHz"; break; case ARN5_LIF_REF_CLK_311 : pS = "311.04 MHz"; break; case ARN5_LIF_REF_CLK_622 : pS = "622.08 MHz"; break; default : pS = "Unknown"; break; } CS_PRINT("Ref Clk = %s\n", pS); switch (pCfg->tx_clk_mode) { case ARN5_LIF_TX_CLK_LOCAL : pS = "Local"; break; case ARN5_LIF_TX_CLK_LOOP_INTERNAL : pS = "Internal Loop"; break; case ARN5_LIF_TX_CLK_LOOP_EXTERNAL : pS = "External Loop"; break; default : pS = "Unknown"; break; } CS_PRINT("Tx Clock Mode = %s\n", pS); CS_PRINT("Clk Div1/2 = 0x%x/0x%x\n", pCfg->div1, pCfg->div2); CS_PRINT("Rx Clkout Ctrl = %s\n", pCfg->rx_clkout_ctl ? "Enabled" : "Disabled"); CS_PRINT("Rx Clkout Sel = 0x%x\n", pCfg->rx_clkout_sel); CS_PRINT("Tx Clkout Ctrl = %s\n", pCfg->tx_clkout_ctl ? "Enabled" : "Disabled"); CS_PRINT("Tx Clkout Sel = 0x%x\n", pCfg->tx_clkout_sel); CS_PRINT("Analog Terminal Lpbk = %s\n", pCfg->analog_term_lb ? "Enabled" : "Disabled"); CS_PRINT("Line Lpbk = %s\n", pCfg->line_loopback ? "Enabled" : "Disabled"); CS_PRINT("Terminal Lpbk = %s\n", pCfg->terminal_loopback ? "Enabled" : "Disabled"); return(CS_OK) ; }
/***************************************** * Initialize device hardware * * All common sections of the chip that * * are shared by all the ports will be * * initialized. * *****************************************/ static cs_status arn5_dev_init_hw(cs_uint8 dev_id, arn5_dev_cfg_t * pDevCfg) { cs_uint32 jtag_id ; jtag_id = arn5_get_chip_jtag_id(dev_id) ; if ( !(ARN5_IS_JTAG_ID_CORRECT(jtag_id)) ) { CS_HNDL_ERROR(dev_id, EARN5_CHIP_JTAG_ID_MISMATCH, ":chip's JTAG Id is 0x%x\n", jtag_id) ; return (CS_ERROR) ; } // CS_PRINT("JTAG ID: 0x%x\n", jtag_id); // bypass bist temperory #if 1 if ( CS_IN_CUSTOMER_ENV() || CS_IN_LAB_ENV() ) { if ( arn5_wait_for_bist_done(dev_id, FALSE, TRUE, 50) != CS_OK ) { return (CS_ERROR) ; } if ( arn5_check_bist_status(dev_id, FALSE, TRUE) != CS_OK ) { CS_PRINT("\n*************************************************\n") ; CS_PRINT("SELF-TEST AND REPAIR(STAR) BIST ERROR !!!!!!\n") ; CS_PRINT("*************************************************\n\n") ; } } #endif if ( arn5_dev_verify_summ(dev_id, &pDevCfg->summ) != CS_OK ) { return (CS_ERROR) ; } if ( arn5_dev_verify_cfg(dev_id, pDevCfg) != CS_OK ) { return (CS_ERROR) ; } /* sync slice enable state with hardware, assume slice 0 must be */ /* powered on */ if ( arn5_slice_ctl_pwr_down(dev_id, 0, CS_DISABLE) != CS_OK ) { return (CS_ERROR) ; } /* from now on, the slice enable is cached for driver to reference */ /* Hard reset the chip */ if ( arn5_dev_hard_reset(dev_id, ARN5_ID_ALL_BLOCKS, CS_RESET_TOGGLE) != CS_OK ) { return (CS_ERROR) ; } /* Configure GPIO */ if ( arn5_mpif_cfg_gpio_alm_status(dev_id, pDevCfg->gpio.alm_status_map, 0xff) != CS_OK ) { return (CS_ERROR) ; } if ( arn5_mpif_cfg_gpio_io(dev_id, (pDevCfg->gpio.io_map | (cs_uint16)pDevCfg->gpio.alm_status_map), 0xffff) != CS_OK ) { return (CS_ERROR) ; } if ( arn5_mpif_write_gpio_output(dev_id, pDevCfg->gpio.output_values, 0xffff) != CS_OK ) { return (CS_ERROR) ; } if ( arn5_mpif_dev_init_irq_cfg(dev_id, &pDevCfg->mpif) != CS_OK ) { return (CS_ERROR) ; } if ( arn5_spi_dev_init_cfg(dev_id, pDevCfg) != CS_OK ) { return (CS_ERROR) ; } return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_dev_dump_vital_status(cs_uint8 dev_id) /* INPUTS : o Device Id */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Retrieves and prints the current status at a glance */ /* This is mainly for debug purpose as most of status are */ /* available via individual API's call. */ /* $rtn_hdr_end */ /****************************************************************/ { arn5_dev_cb_t * pdevcb ; cs_uint8 * str = NULL ; cs_uint32 err_code ; cs_status status = CS_OK ; if ( !(ARN5_IS_DEVICE_VALID(dev_id, &err_code)) ) { CS_HNDL_ERROR(dev_id, err_code, NULL) ; return(CS_ERROR) ; } pdevcb = ARN5_DEV_ID_TO_DEVCB_PTR(dev_id) ; if (pdevcb->state != ARN5_DEV_STATE_INITIALIZED) { /* hwcfg not done */ CS_HNDL_ERROR(dev_id, EARN5_DEV_INVALID_USER_ARG, ": device hw cfg not done yet!\n") ; return (CS_ERROR) ; } CS_PRINT("\n") ; CS_PRINT("\t *** DEVICE-%d Vital Status ***\n", dev_id) ; CS_PRINT("=================================================\n") ; if (arn5_spi_dev_is_in_spi42_mode(dev_id)) { arn5_spi42_sync_t spi42Status ; spi42Status = arn5_spi42_dev_get_sync_state(dev_id, CS_TX) ; if (spi42Status == ARN5_SPI42_IN_SYNC) { str = "In Sync" ; } else if (spi42Status == ARN5_SPI42_INIT_STATE) { str = "Init State" ; } else { str = "Out Of Sync" ; } CS_PRINT("Host SPI4.2 TX Status = %s\n", str) ; spi42Status = arn5_spi42_dev_get_sync_state(dev_id, CS_RX) ; if (spi42Status == ARN5_SPI42_IN_SYNC) { str = "In Sync" ; } else if (spi42Status == ARN5_SPI42_INIT_STATE) { str = "Init State" ; } else { str = "Out Of Sync" ; } CS_PRINT("Host SPI4.2 RX status = %s\n", str) ; } return(status) ; }
/* CHIP : Arsenal5 */ cs_status arn5_dev_get_running_cfg(cs_uint8 dev_id, arn5_dev_runcfg_t * pRunCfg) /* INPUTS : o Device Id */ /* o Pointer to Device Running Configuration */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Get the current run-time hardware configuration for the */ /* specified device(chip). */ /* */ /* The [pRunCfg] parameter is a pointer to the running */ /* configuration data-structure allocated by the caller. */ /* The driver is responsible for filling in ALL the fields in */ /* the datastructure by reading from HW. */ /* $rtn_hdr_end */ /****************************************************************/ { ARN5_t * pDev ; arn5_dev_cb_t * pdevcb ; arn5_dev_summ_t * pSumm ; cs_uint32 err_code ; if ( !(ARN5_IS_DEVICE_VALID(dev_id, &err_code)) ) { CS_HNDL_ERROR(dev_id, err_code, NULL) ; return(CS_ERROR) ; } if ( pRunCfg == NULL ) { CS_HNDL_ERROR(dev_id, EARN5_DEV_CFG_NULL, NULL) ; return (CS_ERROR) ; } pDev = ARN5_DEV_ID_TO_DEV_BASE(dev_id) ; pdevcb = ARN5_DEV_ID_TO_DEVCB_PTR(dev_id) ; CS_MEMSET( (void *)pRunCfg, 0, sizeof(arn5_dev_runcfg_t) ) ; CS_PRINT("ARN5 dev-%d: Retrieving device running configuration..\n", dev_id) ; /* * Get chip's JTAG-Id */ pRunCfg->jtag_id = arn5_get_chip_jtag_id(dev_id) ; /* * Get device summary */ pSumm = &pRunCfg->summ ; pSumm->host_if = ( arn5_spi_dev_is_in_spi42_mode(dev_id) ? ARN5_HOST_IF_SPI42 : ARN5_HOST_IF_SPI3 ) ; /* set block valid flags */ /* GPIO pin configuration */ pRunCfg->gpio.alm_status_map = CS_REG_READ(&pDev->MicroIF.GPIOAlarmControl.wrd) ; pRunCfg->gpio.io_map = ((CS_REG_READ(&pDev->MicroIF.GPIODirection1.wrd) & 0x00ff) << 8) | ((CS_REG_READ(&pDev->MicroIF.GPIODirection0.wrd) & 0x00ff)) ; pRunCfg->gpio.output_values = ((CS_REG_READ(&pDev->MicroIF.GPIOOutput1.wrd) & 0x00ff) << 8) | ((CS_REG_READ(&pDev->MicroIF.GPIOOutput0.wrd) & 0x00ff)) ; /* Block configurations */ if (arn5_spi_dev_get_running_cfg(dev_id, pRunCfg) != CS_OK) { return (CS_ERROR) ; } return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_dev_init(cs_uint8 dev_id, arn5_dev_cfg_t * pDevCfg) /* INPUTS : o Device Id */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Initializes the device state to ready after verifying the */ /* JTAG Id of the chip and hard-resetting and configuring any */ /* HW blocks that are common and shared by all the ports. */ /* */ /* It does NOT do any port related initialization. */ /* */ /* This API should be called only after the device corresponding*/ /* to this port has been registered. */ /* $rtn_hdr_end */ /****************************************************************/ { arn5_dev_cb_t * pdevcb ; cs_uint32 err_code ; if ( !(ARN5_IS_DEVICE_VALID(dev_id, &err_code)) ) { CS_HNDL_ERROR(dev_id, err_code, NULL) ; return (CS_ERROR) ; } pdevcb = ARN5_DEV_ID_TO_DEVCB_PTR(dev_id) ; if (pdevcb == NULL) { CS_PRINT("ARN5 dev-%d %s() ERROR: pdevcb is NULL\n", dev_id, __FUNCTION__) ; return(CS_ERROR) ; } if (pdevcb->state == ARN5_DEV_STATE_INVALID) { CS_PRINT("ARN5 dev-%d %s() ERROR: Device not registered\n", dev_id, __FUNCTION__) ; return(CS_ERROR) ; } if (pdevcb->state == ARN5_DEV_STATE_INITIALIZED) { cs_uint32 base_addr = pdevcb->base_addr ; /* re-init'ing the device - do unreg/reg device again */ arn5_dev_unregister(dev_id) ; arn5_dev_register(dev_id, base_addr) ; /* Need to re-get the pointer because previous structure */ /* has been rebuilt. */ pdevcb = ARN5_DEV_ID_TO_DEVCB_PTR(dev_id) ; } //CS_PRINT(" before arn5_dev_init_data.\n"); if ( arn5_dev_init_data(dev_id, pDevCfg) != CS_OK ) { return (CS_ERROR) ; } //CS_PRINT(" before arn5_dev_init_hw..\n"); if ( arn5_dev_init_hw(dev_id, pDevCfg) != CS_OK ) { return (CS_ERROR) ; } //CS_PRINT("\tARN5 dev-%d initialized: base addr = 0x%x\n", // dev_id, pdevcb->base_addr) ; #ifndef RELEASE_PLATFORM cs_lab_dev_init(CS_CHIP_ARSENAL5, (cs_uint16)dev_id) ; #endif pdevcb->state = ARN5_DEV_STATE_INITIALIZED ; return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_dev_get_default_cfg(cs_uint8 dev_id, arn5_dev_cfg_t * pDevCfg) /* INPUTS : o Device Id */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Get the driver's default DEVICE configuration based on the */ /* configuration summary provided(inside the config data- */ /* structure). */ /* This information will be used by the driver in providing a */ /* default chip configuration. */ /* */ /* Note that, this API does not access or configure the chip and*/ /* only recommends to the caller a recommended configuration. */ /* The caller can choose to use it as is, or with necessary */ /* modifications when initializing the device. */ /* $rtn_hdr_end */ /****************************************************************/ { if ( !(ARN5_DRVR_IS_LOADED()) ) { CS_HNDL_ERROR(dev_id, EARN5_DRVR_NOT_LOADED, NULL) ; return (CS_ERROR) ; } if (dev_id >= ARN5_MAX_NUM_DEVICES) { CS_HNDL_ERROR( dev_id, EARN5_DEV_ID_OUT_OF_RANGE, NULL ) ; return(CS_ERROR) ; } if (pDevCfg == NULL) { CS_PRINT("ARN5 dev-%d: %s() ERROR - pDevCfg is NULL!\n", dev_id, __FUNCTION__) ; return (CS_ERROR) ; } /* * Ensure it is a valid summary before composing the default * configuration. */ if ( arn5_dev_verify_summ(dev_id, &pDevCfg->summ) != CS_OK ) { return (CS_ERROR) ; } /* General Purpose I/O - GPIO[7:0] inputs and GPIO[15:8] outputs */ pDevCfg->gpio.alm_status_map = 0 ; /* pDevCfg->gpio.io_map = 0x00ff ;*/ pDevCfg->gpio.io_map = 0x00f0; pDevCfg->gpio.output_values = 0x0000 ; /* MPIF default IRQ's */ if ( arn5_mpif_dev_get_default_irq_cfg(dev_id, &pDevCfg->summ, &pDevCfg->mpif) != CS_OK ) { return (CS_ERROR) ; } if ( arn5_spi_dev_get_default_cfg(dev_id, pDevCfg) != CS_OK ) { return (CS_ERROR) ; } return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_port_close(cs_uint16 port_id) /* INPUTS : o Port Id */ /* OUTPUTS : ---- */ /* RETURNS : Port Id (or port handle) */ /* DESCRIPTION: */ /* This API deletes the port instance specified. It frees up */ /* all the port data-structures that were dynamically */ /* allocated. */ /* $rtn_hdr_end */ /****************************************************************/ { cs_uint32 err_code ; arn5_port_cb_t * ppcb ; arn5_dev_cb_t * pdcb ; cs_uint8 slice_num, dev_id ; if ( !(ARN5_IS_PORT_VALID(port_id, &err_code)) ) { CS_HNDL_ERROR(port_id, err_code, NULL) ; return (CS_ERROR) ; } pdcb = ARN5_PORT_ID_TO_DEVCB_PTR(port_id) ; ppcb = ARN5_PORT_ID_TO_PCB_PTR(port_id) ; switch (ppcb->summ.line_rate) { case ARN5_PORT_RATE_OC12C : if (pdcb->oc12_num) (pdcb->oc12_num)-- ; pdcb->total_rate_units -= 4 ; break ; case ARN5_PORT_RATE_OC3C : if (pdcb->oc3_num) (pdcb->oc3_num)-- ; pdcb->total_rate_units -= 1 ; break ; case ARN5_PORT_RATE_GIGE : if (pdcb->gige_num) (pdcb->gige_num)-- ; pdcb->total_rate_units -= 7 ; break ; default : if (pdcb->oc48_num) (pdcb->oc48_num)-- ; pdcb->total_rate_units -= 16 ; break ; } /* shut down the slice upon port close */ /* drop the corresponding api chan as well */ slice_num = ARN5_PORT_ID_TO_SLICE_NUM(port_id) ; dev_id = ARN5_PORT_ID_TO_DEV_ID(port_id) ; arn5_spi_drop_chan_data_ctl(dev_id, slice_num, TRUE) ; arn5_slice_ctl_pwr_down(dev_id, slice_num, CS_ENABLE) ; /* Deallocate the semaphores */ arn5_port_destroy_sem(port_id) ; /* Free any dynamically allocated memory */ arn5_port_free_mem(port_id) ; /* Finally, delete the port_id and de-allocate the Port PCB */ arn5_dev_delete_port_id(port_id) ; CS_PRINT("\tPort-0x%04x closed\n", port_id) ; return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_port_get_running_cfg(cs_uint16 port_id, arn5_port_runcfg_t * pRunCfg) /* INPUTS : o Port Id */ /* o Pointer to Port Running Configuration */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Get the current run-time hardware configuration for the */ /* specified device(chip). */ /* */ /* The [pRunCfg] parameter is a pointer to the running */ /* configuration data-structure allocated by the caller. */ /* The driver is responsible for filling in ALL the fields in */ /* the datastructure by reading from HW. */ /* $rtn_hdr_end */ /****************************************************************/ { cs_uint8 dev_id, port_num ; arn5_port_cb_t * ppcb ; cs_uint32 err_code ; if ( pRunCfg == NULL ) { CS_HNDL_ERROR(port_id, EARN5_PORT_CFG_NULL, NULL) ; return (CS_ERROR) ; } if ( !(ARN5_IS_PORT_VALID(port_id, &err_code)) ) { CS_HNDL_ERROR(port_id, err_code, NULL) ; return(CS_ERROR) ; } dev_id = ARN5_PORT_ID_TO_DEV_ID(port_id) ; port_num = ARN5_PORT_ID_TO_PORT_NUM(port_id) ; ppcb = ARN5_PORT_ID_TO_PCB_PTR(port_id) ; CS_MEMSET( (void *)pRunCfg, 0, sizeof(arn5_port_runcfg_t) ) ; CS_PRINT("ARN5 port-0x%x: Retrieving port running cfg...\n", port_id) ; /* * Get driver's dev_id */ pRunCfg->dev_id = dev_id ; /* * Get port summary */ pRunCfg->summ.line_rate = ARN5_GET_LINE_RATE_FROM_HW(port_id) ; pRunCfg->summ.l2_prot = ARN5_GET_L2_PROT_FROM_HW(port_id) ; pRunCfg->eth_valid = (pRunCfg->summ.line_rate == ARN5_PORT_RATE_GIGE) ; pRunCfg->framer_valid = !pRunCfg->eth_valid ; pRunCfg->lif_valid = TRUE ; pRunCfg->pprbs_valid = TRUE ; /* * Get port configuration */ /* spi will get eth info if needed */ if (arn5_spi_get_running_cfg(port_id, pRunCfg) != CS_OK) { return (CS_ERROR) ; } if (pRunCfg->framer_valid) { if (arn5_framer_get_running_cfg(port_id, pRunCfg) != CS_OK) { return (CS_ERROR) ; } } if (pRunCfg->eth_valid) { if (arn5_eth_get_running_cfg(port_id, pRunCfg) != CS_OK) { return (CS_ERROR) ; } } if (arn5_lif_get_running_cfg(port_id, pRunCfg) != CS_OK) { return (CS_ERROR) ; } if (pRunCfg->pprbs_valid) { if (arn5_pprbs_get_running_cfg(port_id, pRunCfg) != CS_OK) { return (CS_ERROR) ; } } return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_dev_print_unit_stats(cs_uint8 dev_id, arn5_module_id_t mod_id, cs_uint16 sect_id, cs_uint16 unit_id) /* INPUTS : o Device Id */ /* o Module ID */ /* o Section ID */ /* o Unit ID */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Prints the Stats for the user specified unit for the device. */ /* Statistics for the device are organised as a collection of block */ /* stats. Each block has number of section stats identified by section */ /* id. Each section then has unit stats. Unit stat is the atomic entity */ /* of the stats and carry RX and TX stats. Each unit is uniquely */ /* identified by block_id, section_id and unit_id combo. */ /* Refer to the individual header files for the section ID and unit_id */ /* defines. */ /* */ /* The [mod_id] parameter is specified as ARN5_ID_HOST_IF only */ /* $rtn_hdr_end */ /************************************************************************/ { cs_uint32 error = 0 ; arn5_stats_sect_cb_t * stats_sect_cb = NULL ; arn5_stats_blk_cb_t * stats_blk_cb ; arn5_stats_data_t * p_unit_data ; if (ARN5_IS_DEVICE_VALID(dev_id, &error) != TRUE) { CS_HNDL_ERROR(dev_id, error, "\n") ; return (CS_ERROR) ; } if (sect_id >= ARN5_STATS_MAX_SECT) { CS_HNDL_ERROR(dev_id, EARN5_DEV_RANGE_ERR, NULL ) ; return (CS_ERROR) ; } stats_blk_cb = arn5_stats_get_blk_cb((cs_uint16)dev_id, ARN5_DEVICE, mod_id) ; if (stats_blk_cb == NULL) { CS_HNDL_ERROR(dev_id, EARN5_DEV_TBL_NULL, "%s not registered for Statistics\n", ARN5_GET_MOD_NAME(mod_id)) ; return (CS_ERROR) ; } if ((stats_sect_cb = stats_blk_cb->p_sect_cb[sect_id]) == NULL) { CS_HNDL_ERROR(dev_id, EARN5_DEV_TBL_NULL, "Section not registered for Statistics (%d)\n", sect_id) ; return (CS_ERROR) ; } if ( stats_sect_cb->enabled == FALSE ) { CS_PRINT("STATISTICS DISABLED FOR %s section %s\n", stats_blk_cb->blk_name, stats_sect_cb->sect_name) ; return (CS_ERROR) ; } p_unit_data = stats_sect_cb->pStats + unit_id ; if (*(stats_sect_cb->enbl_tbl + unit_id) == FALSE) { CS_PRINT("STATS DISABLED FOR %s : SECT_ID : %d UNIT_ID : %d\n", stats_blk_cb->blk_name, sect_id, unit_id) ; return (CS_ERROR) ; } arn5_set_sect_print_flag(0) ; return arn5_stats_unit_cmn_op((cs_uint16)dev_id, ARN5_DEVICE, mod_id, sect_id, unit_id, stats_sect_cb, ARN5_STATS_PRINT, CS_RX_AND_TX, FALSE) ; }
/* CHIP : Arsenal5 */ cs_status arn5_port_dump_running_cfg(cs_uint16 port_id) /* INPUTS : o Port Id */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Retrieves and prints the current run-time hardware */ /* configuration for the specified port. */ /* $rtn_hdr_end */ /****************************************************************/ { arn5_port_runcfg_t * pRunCfg = NULL ; cs_uint32 err_code ; cs_status status = CS_OK ; if ( !(ARN5_IS_PORT_VALID(port_id, &err_code)) ) { CS_HNDL_ERROR(port_id, err_code, NULL) ; return(CS_ERROR) ; } pRunCfg = (arn5_port_runcfg_t *) CS_MALLOC( sizeof(arn5_port_runcfg_t) ) ; if (pRunCfg == NULL) { CS_PRINT("ARN5 port-0x%x ERROR: pRunCfg is NULL\n", port_id) ; return (CS_ERROR) ; } if ( arn5_port_get_running_cfg(port_id, pRunCfg) != CS_OK ) { status = CS_ERROR ; goto RTN_EXIT ; } arn5_print_drvr_ver() ; /* first print driver rel info */ CS_PRINT("\n") ; CS_PRINT("\t\t **************************************\n") ; CS_PRINT("\t\t * PORT-0x%04x RUNNING CONFIGURATION *\n", port_id) ; CS_PRINT("\t\t **************************************\n") ; CS_PRINT("dev_id= 0x%x\n", pRunCfg->dev_id) ; arn5_port_dump_cfg_summ(port_id, &pRunCfg->summ) ; CS_PRINT("=================================================\n") ; CS_PRINT("\t\t SPI Block\n\n") ; if ( arn5_spi_dump_running_cfg(port_id, pRunCfg) != CS_OK ) { status = CS_ERROR ; goto RTN_EXIT ; } CS_PRINT("=================================================\n") ; CS_PRINT("\t\t Framer Block (%s)\n\n", (pRunCfg->framer_valid) ? "valid" : "invalid") ; if (pRunCfg->framer_valid) { if ( arn5_framer_dump_running_cfg(port_id, pRunCfg) != CS_OK ) { status = CS_ERROR ; goto RTN_EXIT ; } } CS_PRINT("=================================================\n") ; CS_PRINT("\t\t ETH Block (%s)\n\n", (pRunCfg->eth_valid) ? "valid" : "invalid") ; if (pRunCfg->eth_valid) { if ( arn5_eth_dump_running_cfg(port_id, pRunCfg) != CS_OK ) { status = CS_ERROR ; goto RTN_EXIT ; } } CS_PRINT("=================================================\n") ; CS_PRINT("\t\t LIF Block\n\n") ; if ( arn5_lif_dump_running_cfg(port_id, pRunCfg) != CS_OK ) { status = CS_ERROR ; goto RTN_EXIT ; } /* pprbs is valid only when any of pprbs gen or checker is enabled */ CS_PRINT("=================================================\n") ; CS_PRINT("\t\t PPRBS Block (%s)\n\n", (pRunCfg->pprbs_valid) ? "valid" : "invalid") ; if (pRunCfg->pprbs_valid) { if ( arn5_pprbs_dump_running_cfg(port_id, pRunCfg) != CS_OK ) { status = CS_ERROR ; goto RTN_EXIT ; } } RTN_EXIT : if (pRunCfg) CS_FREE(pRunCfg) ; return (status) ; }
/* CHIP : Arsenal5 */ cs_status arn5_port_dump_vital_status(cs_uint16 port_id) /* INPUTS : o Port Id */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Retrieves and prints the current status at a glance */ /* This is mainly for debug purpose as most of status are */ /* available via individual API's call. */ /* */ /* This API will dump vital status for the device as well. */ /* $rtn_hdr_end */ /****************************************************************/ { arn5_port_runcfg_t * pRunCfg = NULL ; cs_uint32 err_code ; cs_uint8 devId, portNum ; cs_status status = CS_OK ; if ( !(ARN5_IS_PORT_VALID(port_id, &err_code)) ) { CS_HNDL_ERROR(port_id, err_code, NULL) ; return(CS_ERROR) ; } pRunCfg = (arn5_port_runcfg_t *) CS_MALLOC( sizeof(arn5_port_runcfg_t) ) ; if (pRunCfg == NULL) { return (CS_ERROR) ; } if ( arn5_port_get_running_cfg(port_id, pRunCfg) != CS_OK ) { status = CS_ERROR ; goto RTN_EXIT ; } devId = ARN5_PORT_ID_TO_DEV_ID(port_id) ; portNum = ARN5_PORT_ID_TO_PORT_NUM(port_id) ; arn5_dev_dump_vital_status(devId) ; CS_PRINT("\n") ; CS_PRINT("\t *** PORT-0x%x Vital Status ***\n", port_id) ; CS_PRINT("=================================================\n") ; if (pRunCfg->summ.line_rate == ARN5_PORT_RATE_GIGE) { CS_PRINT("ETH Link Status = %s\n", (arn5_eth_get_link_status(port_id) ? "Link Up" : "Link Down")) ; if (pRunCfg->eth.auto_neg_cfg.enable) { CS_PRINT("ETH Auto_Negotiation Status = %sCompleted\n", (arn5_eth_get_auto_negotiation_status(port_id) ? "" : "Not ")) ; } } else { CS_PRINT("Framer In Frame Status = %s\n", (arn5_framer_get_sync_status(port_id) ? "In Frame" : "Out of Frame")) ; CS_PRINT("Framer Rx Data Path Status = %sReady\n", (arn5_framer_get_rx_data_path_status(port_id) ? "" : "Not ")) ; } if (pRunCfg->pprbs.hostChkr || pRunCfg->pprbs.lineChkr) { /* print pprbs header only if we need to */ CS_PRINT("-- PPRBS --\n") ; } if (pRunCfg->pprbs.hostChkr) { arn5_pprbs_dump_checker(port_id, ARN5_PPRBS_HOST_CHAN) ; } if (pRunCfg->pprbs.lineChkr) { arn5_pprbs_dump_checker(port_id, ARN5_PPRBS_LINE_CHAN) ; } RTN_EXIT : if (pRunCfg) CS_FREE(pRunCfg) ; return(status) ; }
/* CHIP : Arsenal5 */ cs_uint16 arn5_port_open(cs_uint8 dev_id, arn5_port_cfg_t * pCfg, cs_uint8 slice_num) /* INPUTS : o Port Id */ /* o Pointer to port configuration structure */ /* o Slice Number[0..7] to be used for the port */ /* OUTPUTS : ---- */ /* RETURNS : Port Id (or port handle) */ /* DESCRIPTION: */ /* This API, on successful completion, will create a valid */ /* port handle(aka port_id) and also provide the caller with */ /* the driver recommended default configuration for the port. */ /* */ /* The caller of this API is expected to allocate memory for */ /* pCfg and also fill in the summary section in it. */ /* */ /* The port_handle(or port_id) created by the driver should be */ /* used in further invocations of the port-level API's. */ /* $rtn_hdr_end */ /****************************************************************/ { cs_uint32 err_code ; cs_uint16 port_id = ARN5_INVALID_PORT_ID ; arn5_port_cb_t * ppcb ; arn5_dev_cb_t * pdcb ; cs_status status = CS_OK ; cs_uint16 rateUnits, desiredRate ; if (pCfg == NULL) { CS_HNDL_ERROR(dev_id, EARN5_DEV_NULL_PTR, ": pCfg") ; return (CS_ERROR) ; } if ( !(ARN5_IS_DEVICE_VALID(dev_id, &err_code)) ) { CS_HNDL_ERROR(dev_id, err_code, NULL) ; return (CS_ERROR) ; } /* also check if the device has been initialized! */ if (arn5_dev_get_state(dev_id) != ARN5_DEV_STATE_INITIALIZED) { CS_HNDL_ERROR(dev_id, EARN5_DEV_NOT_INITED, NULL) ; return (CS_ERROR) ; } pdcb = ARN5_DEV_ID_TO_DEVCB_PTR(dev_id) ; switch (pCfg->summ.line_rate) { case ARN5_PORT_RATE_OC12C : if ((g_ARN5_ver[slice_num] & 0x4) == 0) { CS_HNDL_ERROR(dev_id, EARN5_DEV_CAPACITY_EXCEEDED , "\nThe slice %d can't be configured as OC12C.\n", slice_num) ; status = CS_ERROR ; goto RTN_EXIT ; } if (pdcb->oc12_num >= g_ARN5_ver[ARN5_MAX_NUM_PORTS + 1]) { CS_HNDL_ERROR(dev_id, EARN5_DEV_CAPACITY_EXCEEDED , "\nToo many OC12C ports are opened.\n") ; status = CS_ERROR ; goto RTN_EXIT ; } rateUnits = 4 ; break ; case ARN5_PORT_RATE_OC3C : if ((g_ARN5_ver[slice_num] & 0x2) == 0) { CS_HNDL_ERROR(dev_id, EARN5_DEV_CAPACITY_EXCEEDED , "\nThe slice %d can't be configured as OC3.\n", slice_num) ; status = CS_ERROR ; goto RTN_EXIT ; } if (pdcb->oc3_num >= g_ARN5_ver[ARN5_MAX_NUM_PORTS + 2]) { CS_HNDL_ERROR(dev_id, EARN5_DEV_CAPACITY_EXCEEDED , "\nToo many OC3C ports are opened.\n") ; status = CS_ERROR ; goto RTN_EXIT ; } rateUnits = 1 ; break ; case ARN5_PORT_RATE_GIGE : if ((g_ARN5_ver[slice_num] & 0x1) == 0) { CS_HNDL_ERROR(dev_id, EARN5_DEV_CAPACITY_EXCEEDED , "\nThe slice %d can't be configured as GigE.\n", slice_num) ; status = CS_ERROR ; goto RTN_EXIT ; } if (pdcb->gige_num >= g_ARN5_ver[ARN5_MAX_NUM_PORTS + 3]) { CS_HNDL_ERROR(dev_id, EARN5_DEV_CAPACITY_EXCEEDED , "\nToo many GigE ports are opened.\n") ; status = CS_ERROR ; goto RTN_EXIT ; } rateUnits = 7 ; break ; default : if ((g_ARN5_ver[slice_num] & 0x8) == 0) { CS_HNDL_ERROR(dev_id, EARN5_DEV_CAPACITY_EXCEEDED , "\nThe slice %d can't be configured as OC48.\n", slice_num) ; status = CS_ERROR ; goto RTN_EXIT ; } if (pdcb->oc48_num >= g_ARN5_ver[ARN5_MAX_NUM_PORTS]) { CS_HNDL_ERROR(dev_id, EARN5_DEV_CAPACITY_EXCEEDED , "\nToo many OC48C ports are opened.\n") ; status = CS_ERROR ; goto RTN_EXIT ; } rateUnits = 16 ; break ; } desiredRate = pdcb->total_rate_units + rateUnits ; if (desiredRate > g_ARN5_ver[ARN5_MAX_NUM_PORTS + 4]) { CS_HNDL_ERROR(dev_id, EARN5_DEV_CAPACITY_EXCEEDED , "\n** Warning!! Total rate exceeds the maximum.\n") ; status = CS_OK ; } switch (arn5_spi_dev_get_if_mode(dev_id)) { case ARN5_SPI3_MODE : if (desiredRate > ARN5_SPI3_MAX_RATE_UNIT) { CS_HNDL_ERROR(dev_id, EARN5_DEV_CAPACITY_EXCEEDED , "\n** Warning!! Total rate exceeds the maximum.\n") ; status = CS_OK ; } break ; case ARN5_SPI42_QUARTER_RATE_MODE : if (desiredRate > ARN5_SPI42Q_MAX_RATE_UNIT) { CS_HNDL_ERROR(dev_id, EARN5_DEV_CAPACITY_EXCEEDED , "\n** Warning!! Total rate exceeds the maximum.\n") ; status = CS_OK ; } break ; default : /* no extra check */ break ; } CS_MEMSET( (void *) ((cs_uint32)pCfg + sizeof(arn5_port_summ_t)), 0, sizeof(arn5_port_cfg_t) - sizeof(arn5_port_summ_t) ) ; if ( arn5_dev_create_port_id(dev_id, &pCfg->summ, &port_id, &ppcb, slice_num) != CS_OK ) { status = CS_ERROR ; goto RTN_EXIT ; } /* clear the Port CB */ CS_MEMSET( (void *) ppcb, 0, sizeof(arn5_port_cb_t) ) ; /* copy some essential info into the port cb */ ppcb->port_id = port_id ; ppcb->state = ARN5_PORT_STATE_OPENED ; ppcb->summ = pCfg->summ ; if ( arn5_port_verify_summ(dev_id, port_id, &pCfg->summ) != CS_OK ) { status = CS_ERROR ; goto RTN_EXIT ; } /* Provide the user with the driver recommended default config */ if ( arn5_port_get_default_cfg(port_id, pCfg) != CS_OK ) { CS_PRINT("dev-%d %s() ERROR: Cannot get default cfg!\n", dev_id, __FUNCTION__) ; status = CS_ERROR ; goto RTN_EXIT ; } arn5_port_commit_default_cfg(port_id, pCfg) ; //CS_PRINT("\tARN5 Port(port-id = port handle = 0x%04x) successfully opened\n", // port_id) ; switch (pCfg->summ.line_rate) { case ARN5_PORT_RATE_OC12C : (pdcb->oc12_num)++ ; break ; case ARN5_PORT_RATE_OC3C : (pdcb->oc3_num)++ ; break ; case ARN5_PORT_RATE_GIGE : (pdcb->gige_num)++ ; break ; default : (pdcb->oc48_num)++ ; break ; } pdcb->total_rate_units += rateUnits ; RTN_EXIT : if ( (status != CS_OK) && (port_id != ARN5_INVALID_PORT_ID) ) { arn5_dev_delete_port_id(port_id) ; port_id = ARN5_INVALID_PORT_ID ; } return (port_id) ; }
uint32_t objToBin(const uint8_t* _objData , bx::WriterSeekerI* _writer , uint32_t _packUv , uint32_t _packNormal , bool _ccw , bool _flipV , bool _hasTangent , float _scale ) { int64_t parseElapsed = -bx::getHPCounter(); int64_t triReorderElapsed = 0; const int64_t begin = _writer->seek(); Vector3Array positions; Vector3Array normals; Vector3Array texcoords; Index3Map indexMap; TriangleArray triangles; BgfxGroupArray groups; uint32_t num = 0; MeshGroup group; group.m_startTriangle = 0; group.m_numTriangles = 0; group.m_name = ""; group.m_material = ""; char commandLine[2048]; uint32_t len = sizeof(commandLine); int argc; char* argv[64]; const char* next = (const char*)_objData; do { next = bx::tokenizeCommandLine(next, commandLine, len, argc, argv, BX_COUNTOF(argv), '\n'); if (0 < argc) { if (0 == strcmp(argv[0], "#") ) { if (2 < argc && 0 == strcmp(argv[2], "polygons") ) { } } else if (0 == strcmp(argv[0], "f") ) { Triangle triangle; memset(&triangle, 0, sizeof(Triangle) ); const int numNormals = (int)normals.size(); const int numTexcoords = (int)texcoords.size(); const int numPositions = (int)positions.size(); for (uint32_t edge = 0, numEdges = argc-1; edge < numEdges; ++edge) { Index3 index; index.m_texcoord = 0; index.m_normal = 0; index.m_vertexIndex = -1; char* vertex = argv[edge+1]; char* texcoord = strchr(vertex, '/'); if (NULL != texcoord) { *texcoord++ = '\0'; char* normal = strchr(texcoord, '/'); if (NULL != normal) { *normal++ = '\0'; const int nn = atoi(normal); index.m_normal = (nn < 0) ? nn+numNormals : nn-1; } const int tex = atoi(texcoord); index.m_texcoord = (tex < 0) ? tex+numTexcoords : tex-1; } const int pos = atoi(vertex); index.m_position = (pos < 0) ? pos+numPositions : pos-1; uint64_t hash0 = index.m_position; uint64_t hash1 = uint64_t(index.m_texcoord)<<20; uint64_t hash2 = uint64_t(index.m_normal)<<40; uint64_t hash = hash0^hash1^hash2; CS_STL::pair<Index3Map::iterator, bool> result = indexMap.insert(CS_STL::make_pair(hash, index) ); if (!result.second) { Index3& oldIndex = result.first->second; BX_UNUSED(oldIndex); BX_CHECK(oldIndex.m_position == index.m_position && oldIndex.m_texcoord == index.m_texcoord && oldIndex.m_normal == index.m_normal , "Hash collision!" ); } switch (edge) { case 0: case 1: case 2: triangle.m_index[edge] = hash; if (2 == edge) { if (_ccw) { std::swap(triangle.m_index[1], triangle.m_index[2]); } triangles.push_back(triangle); } break; default: if (_ccw) { triangle.m_index[2] = triangle.m_index[1]; triangle.m_index[1] = hash; } else { triangle.m_index[1] = triangle.m_index[2]; triangle.m_index[2] = hash; } triangles.push_back(triangle); break; } } } else if (0 == strcmp(argv[0], "g") ) { if (1 >= argc) { CS_PRINT("Error parsing *.obj file.\n"); return 0; } group.m_name = argv[1]; } else if (*argv[0] == 'v') { group.m_numTriangles = (uint32_t)(triangles.size() ) - group.m_startTriangle; if (0 < group.m_numTriangles) { groups.push_back(group); group.m_startTriangle = (uint32_t)(triangles.size() ); group.m_numTriangles = 0; } if (0 == strcmp(argv[0], "vn") ) { Vector3 normal; normal.x = (float)atof(argv[1]); normal.y = (float)atof(argv[2]); normal.z = (float)atof(argv[3]); normals.push_back(normal); } else if (0 == strcmp(argv[0], "vp") ) { static bool once = true; if (once) { once = false; CS_PRINT("warning: 'parameter space vertices' are unsupported.\n"); } } else if (0 == strcmp(argv[0], "vt") ) { Vector3 texcoord; texcoord.x = (float)atof(argv[1]); texcoord.y = 0.0f; texcoord.z = 0.0f; switch (argc) { case 4: texcoord.z = (float)atof(argv[3]); // fallthrough case 3: texcoord.y = (float)atof(argv[2]); break; default: break; } texcoords.push_back(texcoord); } else { float px = (float)atof(argv[1]); float py = (float)atof(argv[2]); float pz = (float)atof(argv[3]); float pw = 1.0f; if (argc > 4) { pw = (float)atof(argv[4]); } float invW = _scale/pw; px *= invW; py *= invW; pz *= invW; Vector3 pos; pos.x = px; pos.y = py; pos.z = pz; positions.push_back(pos); } } else if (0 == strcmp(argv[0], "usemtl") ) { std::string material(argv[1]); if (material != group.m_material) { group.m_numTriangles = (uint32_t)(triangles.size() ) - group.m_startTriangle; if (0 < group.m_numTriangles) { groups.push_back(group); group.m_startTriangle = (uint32_t)(triangles.size() ); group.m_numTriangles = 0; } } group.m_material = material; } // unsupported tags // else if (0 == strcmp(argv[0], "mtllib") ) // { // } // else if (0 == strcmp(argv[0], "o") ) // { // } // else if (0 == strcmp(argv[0], "s") ) // { // } } ++num; } while ('\0' != *next); group.m_numTriangles = (uint32_t)(triangles.size() ) - group.m_startTriangle; if (0 < group.m_numTriangles) { groups.push_back(group); group.m_startTriangle = (uint32_t)(triangles.size() ); group.m_numTriangles = 0; } int64_t now = bx::getHPCounter(); parseElapsed += now; int64_t convertElapsed = -now; std::sort(groups.begin(), groups.end(), GroupSortByMaterial() ); bool hasColor = false; bool hasNormal; bool hasTexcoord; { Index3Map::const_iterator it = indexMap.begin(); hasNormal = 0 != it->second.m_normal; hasTexcoord = 0 != it->second.m_texcoord; if (!hasTexcoord && texcoords.size() == positions.size() ) { hasTexcoord = true; for (Index3Map::iterator it = indexMap.begin(), itEnd = indexMap.end(); it != itEnd; ++it) { it->second.m_texcoord = it->second.m_position; } } if (!hasNormal && normals.size() == positions.size() ) { hasNormal = true; for (Index3Map::iterator it = indexMap.begin(), itEnd = indexMap.end(); it != itEnd; ++it) { it->second.m_normal = it->second.m_position; } } } bgfx::VertexDecl decl; decl.begin(); decl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float); if (hasColor) { decl.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true); } if (hasTexcoord) { switch (_packUv) { default: case 0: decl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float); break; case 1: decl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Half); break; } } if (hasNormal) { _hasTangent &= hasTexcoord; switch (_packNormal) { default: case 0: decl.add(bgfx::Attrib::Normal, 3, bgfx::AttribType::Float); if (_hasTangent) { decl.add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Float); } break; case 1: decl.add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true); if (_hasTangent) { decl.add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Uint8, true, true); } break; } } decl.end(); uint32_t stride = decl.getStride(); uint8_t* vertexData = new uint8_t[triangles.size() * 3 * stride]; uint16_t* indexData = new uint16_t[triangles.size() * 3]; int32_t numVertices = 0; int32_t numIndices = 0; int32_t numPrimitives = 0; uint8_t* vertices = vertexData; uint16_t* indices = indexData; std::string material = groups.begin()->m_material; BgfxPrimitiveArray primitives; Primitive prim; prim.m_startVertex = 0; prim.m_startIndex = 0; uint32_t positionOffset = decl.getOffset(bgfx::Attrib::Position); uint32_t color0Offset = decl.getOffset(bgfx::Attrib::Color0); uint32_t ii = 0; for (BgfxGroupArray::const_iterator groupIt = groups.begin(); groupIt != groups.end(); ++groupIt, ++ii) { for (uint32_t tri = groupIt->m_startTriangle, end = tri + groupIt->m_numTriangles; tri < end; ++tri) { if (material != groupIt->m_material || 65533 < numVertices) { prim.m_numVertices = numVertices - prim.m_startVertex; prim.m_numIndices = numIndices - prim.m_startIndex; if (0 < prim.m_numVertices) { primitives.push_back(prim); } triReorderElapsed -= bx::getHPCounter(); for (BgfxPrimitiveArray::const_iterator primIt = primitives.begin(); primIt != primitives.end(); ++primIt) { const Primitive& prim = *primIt; triangleReorder(indexData + prim.m_startIndex, prim.m_numIndices, numVertices, 32); } triReorderElapsed += bx::getHPCounter(); if (_hasTangent) { calculateTangents(vertexData, numVertices, decl, indexData, numIndices); } write(_writer , vertexData , numVertices , decl , indexData , numIndices , material.c_str() , primitives.data() , (uint32_t)primitives.size() ); primitives.clear(); for (Index3Map::iterator indexIt = indexMap.begin(); indexIt != indexMap.end(); ++indexIt) { indexIt->second.m_vertexIndex = -1; } vertices = vertexData; indices = indexData; numVertices = 0; numIndices = 0; prim.m_startVertex = 0; prim.m_startIndex = 0; ++numPrimitives; material = groupIt->m_material; } Triangle& triangle = triangles[tri]; for (uint32_t edge = 0; edge < 3; ++edge) { uint64_t hash = triangle.m_index[edge]; Index3& index = indexMap[hash]; if (index.m_vertexIndex == -1) { index.m_vertexIndex = numVertices++; float* position = (float*)(vertices + positionOffset); memcpy(position, &positions[index.m_position], 3*sizeof(float) ); if (hasColor) { uint32_t* color0 = (uint32_t*)(vertices + color0Offset); *color0 = rgbaToAbgr(numVertices%255, numIndices%255, 0, 0xff); } if (hasTexcoord) { float uv[2]; memcpy(uv, &texcoords[index.m_texcoord], 2*sizeof(float) ); if (_flipV) { uv[1] = -uv[1]; } bgfx::vertexPack(uv, true, bgfx::Attrib::TexCoord0, decl, vertices); } if (hasNormal) { float normal[4]; bx::vec3Norm(normal, (float*)&normals[index.m_normal]); bgfx::vertexPack(normal, true, bgfx::Attrib::Normal, decl, vertices); } vertices += stride; } *indices++ = (uint16_t)index.m_vertexIndex; ++numIndices; } } if (0 < numVertices) { prim.m_numVertices = numVertices - prim.m_startVertex; prim.m_numIndices = numIndices - prim.m_startIndex; bx::strlcpy(prim.m_name, groupIt->m_name.c_str(), 128); primitives.push_back(prim); prim.m_startVertex = numVertices; prim.m_startIndex = numIndices; } //CS_PRINT("%3d: s %5d, n %5d, %s\n" // , ii // , groupIt->m_startTriangle // , groupIt->m_numTriangles // , groupIt->m_material.c_str() // ); } if (0 < primitives.size() ) { triReorderElapsed -= bx::getHPCounter(); for (BgfxPrimitiveArray::const_iterator primIt = primitives.begin(); primIt != primitives.end(); ++primIt) { const Primitive& prim = *primIt; triangleReorder(indexData + prim.m_startIndex, prim.m_numIndices, numVertices, 32); } triReorderElapsed += bx::getHPCounter(); if (_hasTangent) { calculateTangents(vertexData, numVertices, decl, indexData, numIndices); } write(_writer, vertexData, numVertices, decl, indexData, numIndices, material.c_str(), primitives.data(), (uint32_t)primitives.size()); } delete [] indexData; delete [] vertexData; now = bx::getHPCounter(); convertElapsed += now; const int64_t end = _writer->seek(); const uint32_t dataSize = uint32_t(end-begin); CS_PRINT("size: %u\n", dataSize); CS_PRINT("parse %f [s]\ntri reorder %f [s]\nconvert %f [s]\n# %d, g %d, p %d, v %d, i %d\n" , double(parseElapsed)/bx::getHPFrequency() , double(triReorderElapsed)/bx::getHPFrequency() , double(convertElapsed)/bx::getHPFrequency() , num , uint32_t(groups.size() ) , numPrimitives , numVertices , numIndices ); return dataSize; }