/****************************************************************************** * * f2_phy_get_duplex - Determines the speed of phy ports associated with the * specified device. * * RETURNS: * AG7100_PHY_SPEED_10T, AG7100_PHY_SPEED_100TX; * AG7100_PHY_SPEED_1000T; */ sw_error_t f2_phy_get_duplex(a_uint32_t dev_id, a_uint32_t phy_id, fal_port_duplex_t * duplex) { a_uint16_t phy_data; #if 0 //a_uint16_t ii = 200; a_uint16_t ii = 2; if (phy_id >= F2_PHY_MAX) return SW_BAD_PARAM; do { phy_data = f2_phy_reg_read(dev_id, phy_id, F2_PHY_SPEC_STATUS); aos_mdelay(10); } while ((!(phy_data & F2_STATUS_RESOVLED)) && --ii); //read time out if (ii == 0) return SW_DISABLE; #endif phy_data = f2_phy_reg_read(dev_id, phy_id, F2_PHY_SPEC_STATUS); //read duplex if (phy_data & F2_STATUS_FULL_DUPLEX) *duplex = FAL_FULL_DUPLEX; else *duplex = FAL_HALF_DUPLEX; return SW_OK; }
/****************************************************************************** * * f1_phy_cdt - cable diagnostic test * * cable diagnostic test */ sw_error_t f1_phy_cdt(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t mdi_pair, fal_cable_status_t *cable_status, a_uint32_t *cable_len) { a_uint16_t status = 0; a_uint16_t ii = 100; if(!cable_status || !cable_len) { return SW_FAIL; } if(mdi_pair >= 4) { //There are only 4 mdi pairs in 1000BASE-T return SW_BAD_PARAM; } a_uint16_t org_debug_value = f1_phy_debug_read(dev_id, phy_id, 0x3f); /*disable clock gating*/ f1_phy_debug_write(dev_id, phy_id, 0x3f, 0); f1_phy_reg_write(dev_id, phy_id, F1_PHY_CDT_CONTROL, (mdi_pair << 8) | 0x0001); do { aos_mdelay(30); status = f1_phy_reg_read(dev_id, phy_id, F1_PHY_CDT_CONTROL); } while ((status & 0x0001) && (--ii)); status = f1_phy_reg_read(dev_id, phy_id, F1_PHY_CDT_STATUS); *cable_status = (status&0x300) >> 8; if ( (*cable_status == 1) || (*cable_status == 2)) { if ( mdi_pair == 1 || mdi_pair == 3 ) { /*Reverse the mdi status for channel 1 and channel 3*/ *cable_status = (~(*cable_status)) & 0x3; } } /* the actual cable length equals to CableDeltaTime * 0.824*/ a_uint16_t cable_delta_time = status & 0xff; *cable_len = (cable_delta_time * 824) /1000; /*restore debug port value*/ f1_phy_debug_write(dev_id, phy_id, 0x3f, org_debug_value); //f1_phy_reg_write(dev_id, phy_id, 0x00, 0x9000);//Reset the PHY if necessary return SW_OK; }
/****************************************************************************** * * f1_phy_on - power on the phy after speed changed * * Power on the phy */ sw_error_t f1_phy_poweron(a_uint32_t dev_id, a_uint32_t phy_id) { a_uint16_t phy_data; phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_CONTROL); f1_phy_reg_write(dev_id, phy_id, F1_PHY_CONTROL, phy_data & ~F1_CTRL_POWER_DOWN); aos_mdelay(200); return SW_OK; }
/****************************************************************************** * * f1_phy_Speed_Duplex_Resolved - reset the phy * * reset the phy */ a_bool_t f1_phy_speed_duplex_resolved(a_uint32_t dev_id, a_uint32_t phy_id) { a_uint16_t phy_data; a_uint16_t ii = 200; do { phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_SPEC_STATUS); aos_mdelay(10); } while ((!F1_SPEED_DUPLEX_RESOVLED(phy_data)) && --ii); if (ii == 0) return A_FALSE; return A_TRUE; }
/****************************************************************************** * * f1_autoneg_done * * f1_autoneg_done */ a_bool_t f1_autoneg_done(a_uint32_t dev_id, a_uint32_t phy_id) { a_uint16_t phy_data; a_uint16_t ii = 200; do { phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_STATUS); aos_mdelay(10); } while ((!F1_AUTONEG_DONE(phy_data)) && --ii); if (ii == 0) return A_FALSE; return A_TRUE; }
/****************************************************************************** * * f1_phy_reset_done - reset the phy * * reset the phy */ a_bool_t f1_phy_reset_done(a_uint32_t dev_id, a_uint32_t phy_id) { a_uint16_t phy_data; a_uint16_t ii = 200; do { phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_CONTROL); aos_mdelay(10); } while ((!F1_RESET_DONE(phy_data)) && --ii); if (ii == 0) return A_FALSE; return A_TRUE; }
/****************************************************************************** * * f2_phy_cdt - cable diagnostic test * * cable diagnostic test */ sw_error_t f2_phy_cdt(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t mdi_pair, fal_cable_status_t *cable_status, a_uint32_t *cable_len) { a_uint16_t status = 0; a_uint16_t ii = 100; if(!cable_status || !cable_len) { return SW_FAIL; } if(mdi_pair >= 2) { //There are only 4 mdi pairs in 1000BASE-T return SW_BAD_PARAM; } f2_phy_reg_write(dev_id, phy_id, F2_PHY_CDT_CONTROL, (mdi_pair << 8) | 0x0001); do { aos_mdelay(30); status = f2_phy_reg_read(dev_id, phy_id, F2_PHY_CDT_CONTROL); } while ((status & 0x0001) && (--ii)); status = f2_phy_reg_read(dev_id, phy_id, F2_PHY_CDT_STATUS); *cable_status = (status & 0x300) >> 8;//(00:normal 01:short 10:opened 11:invalid) /*the actual cable length equals to CableDeltaTime * 0.824*/ a_uint16_t cable_delta_time = status & 0xff; *cable_len = (cable_delta_time * 824) /1000; /*workaround*/ if(*cable_len <= 2 && *cable_status == 1) *cable_status = 2; //f2_phy_reg_write(dev_id, phy_id, 0x00, 0x9000); //Reset the PHY if necessary return SW_OK; }
/** * @brief Init hsl layer. * @details Comments: * This operation will init hsl layer and hsl layer * @param[in] dev_id device id * @param[in] cfg configuration for initialization * @return SW_OK or error code */ sw_error_t garuda_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) { a_uint8_t *p_mem; HSL_DEV_ID_CHECK(dev_id); p_mem = (a_uint8_t *)garuda_cfg[dev_id]; if (NULL == p_mem) { p_mem = aos_mem_alloc(sizeof (ssdk_init_cfg) + sizeof(garuda_init_spec_cfg)); garuda_cfg[dev_id] = (ssdk_init_cfg *)p_mem; garuda_cfg[dev_id]->chip_spec_cfg = (garuda_init_spec_cfg *) (p_mem + sizeof (ssdk_init_cfg)); } if (NULL == p_mem) { return SW_OUT_OF_MEM; } aos_mem_copy(garuda_cfg[dev_id]->chip_spec_cfg, cfg->chip_spec_cfg, sizeof (garuda_init_spec_cfg)); aos_mem_copy(garuda_cfg[dev_id], cfg, sizeof (ssdk_init_cfg)); garuda_cfg[dev_id]->chip_spec_cfg = (garuda_init_spec_cfg *) (p_mem + sizeof (ssdk_init_cfg)); SW_RTN_ON_ERROR(garuda_reg_access_init(dev_id, cfg->reg_mode)); SW_RTN_ON_ERROR(garuda_dev_init(dev_id, cfg->cpu_mode)); #if !(defined(KERNEL_MODULE) && defined(USER_MODE)) { a_uint32_t i, entry; sw_error_t rv; if(HSL_MDIO == cfg->reg_mode) { SW_RTN_ON_ERROR(garuda_bist_test(dev_id)); entry = 0x1; HSL_REG_FIELD_SET(rv, dev_id, MASK_CTL, 0, SOFT_RST, (a_uint8_t *) (&entry), sizeof (a_uint32_t)); SW_RTN_ON_ERROR(rv); i = 0x10; do { HSL_REG_FIELD_GET(rv, dev_id, MASK_CTL, 0, SOFT_RST, (a_uint8_t *) (&entry), sizeof (a_uint32_t)); SW_RTN_ON_ERROR(rv); aos_mdelay(10); } while (entry && --i); if (0 == i) { return SW_INIT_ERROR; } } SW_RTN_ON_ERROR(hsl_port_prop_init()); SW_RTN_ON_ERROR(hsl_port_prop_init_by_dev(dev_id)); SW_RTN_ON_ERROR(garuda_portproperty_init(dev_id, cfg->cpu_mode)); GARUDA_MIB_INIT(rv, dev_id); GARUDA_PORT_CTRL_INIT(rv, dev_id); GARUDA_PORTVLAN_INIT(rv, dev_id); GARUDA_VLAN_INIT(rv, dev_id); GARUDA_FDB_INIT(rv, dev_id); GARUDA_QOS_INIT(rv, dev_id); GARUDA_STP_INIT(rv, dev_id); GARUDA_MIRR_INIT(rv, dev_id); GARUDA_RATE_INIT(rv, dev_id); GARUDA_MISC_INIT(rv, dev_id); GARUDA_LEAKY_INIT(rv, dev_id); GARUDA_IGMP_INIT(rv, dev_id); GARUDA_ACL_INIT(rv, dev_id); GARUDA_LED_INIT(rv, dev_id); { hsl_api_t *p_api; SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); p_api->dev_reset = garuda_reset; p_api->dev_clean = garuda_cleanup; } if(cfg->reg_mode == HSL_MDIO) { SW_RTN_ON_ERROR(garuda_hw_init(dev_id, cfg)); } } #endif return SW_OK; }
/** * @brief Init hsl layer. * @details Comments: * This operation will init hsl layer and hsl layer * @param[in] dev_id device id * @param[in] cfg configuration for initialization * @return SW_OK or error code */ sw_error_t horus_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) { HSL_DEV_ID_CHECK(dev_id); if (NULL == horus_cfg[dev_id]) { horus_cfg[dev_id] = aos_mem_alloc(sizeof (ssdk_init_cfg)); } if (NULL == horus_cfg[dev_id]) { return SW_OUT_OF_MEM; } aos_mem_copy(horus_cfg[dev_id], cfg, sizeof (ssdk_init_cfg)); SW_RTN_ON_ERROR(horus_reg_access_init(dev_id, cfg->reg_mode)); SW_RTN_ON_ERROR(horus_dev_init(dev_id, cfg->cpu_mode)); #if !(defined(KERNEL_MODULE) && defined(USER_MODE)) { a_uint32_t i, entry; sw_error_t rv; SW_RTN_ON_ERROR(horus_bist_test(dev_id)); entry = 0x1; HSL_REG_FIELD_SET(rv, dev_id, MASK_CTL, 0, SOFT_RST, (a_uint8_t *) (&entry), sizeof (a_uint32_t)); SW_RTN_ON_ERROR(rv); i = 0x10; do { HSL_REG_FIELD_GET(rv, dev_id, MASK_CTL, 0, SOFT_RST, (a_uint8_t *) (&entry), sizeof (a_uint32_t)); SW_RTN_ON_ERROR(rv); aos_mdelay(10); } while (entry && --i); if (0 == i) { return SW_INIT_ERROR; } SW_RTN_ON_ERROR(hsl_port_prop_init()); SW_RTN_ON_ERROR(hsl_port_prop_init_by_dev(dev_id)); SW_RTN_ON_ERROR(horus_portproperty_init(dev_id, cfg->cpu_mode)); HORUS_MIB_INIT(rv, dev_id); HORUS_PORT_CTRL_INIT(rv, dev_id); HORUS_PORTVLAN_INIT(rv, dev_id); HORUS_VLAN_INIT(rv, dev_id); HORUS_FDB_INIT(rv, dev_id); HORUS_QOS_INIT(rv, dev_id); HORUS_STP_INIT(rv, dev_id); HORUS_MIRR_INIT(rv, dev_id); HORUS_RATE_INIT(rv, dev_id); HORUS_MISC_INIT(rv, dev_id); HORUS_LEAKY_INIT(rv, dev_id); HORUS_IGMP_INIT(rv, dev_id); HORUS_LED_INIT(rv, dev_id); { hsl_api_t *p_api; SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); p_api->dev_reset = horus_reset; p_api->dev_clean = horus_cleanup; } SW_RTN_ON_ERROR(horus_hw_init(dev_id, cfg)); } #endif return SW_OK; }