⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stp_appl.c

📁 stp代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    stp_id_t tree_id;
    bcm_stg_t stg;

    tree_id = stp->external_id;
    /*修改的代码  zhouguis modified 2005-12-1*/
    stg = find_newstg_forvlan(tree_id);
    for (unit = 0; unit < stp_all_units_onboard; unit++) {
        /*
         * Get the link status of all the ports that belong to this VLAN
         */
        if(tree_id==1){
             /* 缺省VLAN对应缺省STG */
        	    bcm_stg_vlan_add(unit, 1, tree_id);  
        }
        else{
              bcm_stg_create_id(unit, stg);
              bcm_stg_vlan_add(unit, stg, tree_id); 
        }
        #if BOARD_TYPE==RHS8012GE_3T8F
        bcm_stg_stp_set(unit, stg, 13, STP_FORWARDING); 
        #else 
        bcm_stg_stp_set(unit, stg, 12, STP_FORWARDING); 
        #endif       

        /* make high speed port to forwarding  added by zhouguis 2005-12-7*/
        bcm_vlan_port_get(unit, tree_id, &pbmp, NULL);
        SOC_PBMP_AND(pbmp, PBMP_E_ALL(unit));
        PBMP_ITER(pbmp, pport) {
            lport = stp_port_p2l(stp_my_cpuid, unit, pport);

            if (bcm_stk_port_is_stack(unit, pport)) {
                stp_mark_stack_port(stp, lport);
                if (stk_mode) {
                    stp_send_port_info(tree_id, lport, STP_PORT_INFO_STACK, 1, 0);
                }
                continue;
            }

            if (bcm_port_link_status_get(unit, pport, &link) < 0) {
                trace(TRACE_STP, TR_ERROR, "bcm_port_link_status_get error\n");
                continue;
            }

            if (link) {
                stp_port_t *stport;

                if (bcm_port_speed_get(unit, pport, &speed) < 0) {
                    trace(TRACE_STP, TR_ERROR, "bcm_port_speed_get error\n");
                    speed = 100;
                }

                if (stp_create_stp_port(&stport, stp, lport, "stp port") < 0) {
                    return;
                }
                stport->cpu = stp_my_cpuid;
                stport->unit = unit;
                stport->port = pport;
                stport->port_type = stp_get_porttype(unit, pport);
                stport->link_flags |= STP_LF_LOCAL;
                /* for port id = pri + port id zhouguis adde 2005-12-22*/
                gport = get_global_port(unit,pport);
                stport->port_id |= gport;
                stp_link_up(stp, stport, speed);

                if (stk_mode) {
                    stp_send_port_info(tree_id, lport, STP_PORT_INFO_LINK,
                                       speed, stport->port_type);
                }

            }
        }
    }
}

/*
 * Function:
 *     stp_sys_init
 * Purpose:
 *     System initialization before STP is run,
 *     set up COS for BPDU packets, register link scan callback,
 *     register with PMUX to receive BPDU packets.
 * Note:
 *     This function tries to start PMUX if not already active.
 *     If STP runs in stack mode, MDP also tries to start PMUX,
 *     Because PMUX will remember whether in SL stack mode or not
 *     at the start, it is very important stp_sys_init() is called
 *     after the mdp_start() is called if intended to run
 *     STP in stack mode.  Otherwise, the packet parsing will
 *     be totally screwed up because of the actual stack tag
 *     mismatch with what PMUX remembered when PMUX starts.
 */
int
stp_sys_init(void)
{
    int unit;
    int rv;

    /* 清除vlan和stg对应表 zhouguis added this 2005-11-20 */
    init_clear_all_mapping_table();
    
    if(rhosStpLock == NULL){
         rhosStpLock = semBCreate (SEM_Q_FIFO, SEM_FULL);
    }
    if(rhosStpLock == NULL){
    	return -1;
    }    
    /* Set up packet receive queue */
    stp_pakq_int(STP_QUEUE_SIZE);

    rv = rhos_start_interface();/*added by kevin 2005.2.1*/
    if(rv != OK)
    {
    	trace(TRACE_STP, TR_ERROR, "bcm_pmux_start failed\n");
        return -1;
    }
    
    for (unit = 0; unit < stp_all_units_onboard; unit++) 
    {
        /* BPDU packets should use the best COS */
        stp_bpdu_cos_set(unit);

        /* register link scan callback function */
        if (bcm_linkscan_register(unit, stp_link_scan_callback) != BCM_E_NONE) 
        {
            trace(TRACE_STP, TR_ERROR, "Cannot register linkscan callback\n");
            return (-1);
        }
#if 0  /*removed by kevin 2005.2.1*/
        /* Start packet reception via PMUX */
        if (!bcm_pmux_active(unit, NULL, NULL, NULL))
        {
            rv = bcm_pmux_start(unit, ENET_MAX_SIZE, stp_sys_alloc, stp_sys_free);
            if (rv != BCM_E_NONE) {
                trace(TRACE_STP, TR_ERROR, "bcm_pmux_start failed\n");
                return -1;
            }
        }
#endif
        /*BCM_PMUX_PRIO_STP should higer than BCM_PMUX_PRIO_AMUX*/
        if ((rv = bcm_pmux_info_register(unit, "STP", 0, BCM_PMUX_PRIO_STP,/*BCM_PMUX_PRIO_AMUX,*/
                       stp_sys_recv_pkts, NULL)) != BCM_E_NONE) 
        {
            trace(TRACE_STP, TR_ERROR, "bcm_pmux_info_register failed\n");
            return -1;
        }
    }

    return 0;
}

/*
 * Function:
 *     stp_sys_cleanup
 * Purpose:
 *     Cleanup resources used by STP. Unregister port scan
 *     callback, stop STP config packet receive.
 */
void
stp_sys_cleanup(void)
{
    int unit;

    for (unit = 0; unit < stp_all_units_onboard; unit++) {
        bcm_pmux_info_unregister(unit, BCM_PMUX_PRIO_STP, stp_sys_recv_pkts);
        bcm_linkscan_unregister(unit, stp_link_scan_callback);
    }

    if (stp_stack_mode) {
        mdp_unregister_callback(stp_do_start_mode);
        rdp_rcv_unregister(BCM_RDP_ID_STP, stp_rcv_rdp_data);
    }

    stp_my_cpuid = stp_stk_num_cpu = 1;
    stp_stack_port = 0;
    stp_stack_mode = stp_stack_ready = FALSE;
    stp_sys_initialized = 0;
}

/*
 * return the number of prts for a chip type
 */
static int
stp_get_num_ports(int type)
{
    switch (type) {
      case SOC_CHIP_BCM5600:
      case SOC_CHIP_BCM5605:
      case SOC_CHIP_BCM5615:
        return (26);
      case SOC_CHIP_BCM5680:
        return (8);
      case SOC_CHIP_BCM5690:
        return (13);
      case SOC_CHIP_BCM5670:
        return (8);
    }

    return (0);
}

/*
 * Get all the stack module info we need
 */
static int
stp_save_stk_info(int stk_mode)
{
    bcm_l2_addr_t l2addr;
    int cpu, unit;

    if (!stk_mode) {        /* stand alone mode */
        char *sys_addr;
        sys_addr = sal_config_get(SAL_CONFIG_SWITCH_MAC);
        parse_macaddr(sys_addr, stp_stk_modinfo[1].cpu_mcadd);

        stp_my_cpuid = 1;
        stp_stk_num_cpu = 1;

        stp_stk_modinfo[1].num_chip = stp_all_units_onboard;
        for (unit = 0; unit < stp_all_units_onboard; unit++) {
            stp_stk_modinfo[1].chip[unit].soc_unit = unit;
            stp_stk_modinfo[1].chip[unit].chip_type = SOC_CHIP_GROUP(unit);
        }
    } else {                 /* stacking mode */
        mdp_num_cpu_get(&stp_stk_num_cpu);
        mdp_cpuid_get(&stp_my_cpuid);

        for (cpu = 1; cpu <= stp_stk_num_cpu; cpu++) {
            mdp_cpu_info_get(cpu, &stp_stk_modinfo[cpu]);
        }
    }

    /*
     * Save the bridge ID, it is the CPU mac address(master's in stack mode)
     */
    sal_memcpy(stp_bridge_mac, stp_stk_modinfo[1].cpu_mcadd, sizeof(mac_addr_t));

    bcm_l2_addr_init(&l2addr, stp_bridge_mac, 1);
    l2addr.flags |= BCM_L2_STATIC; 
    for (unit = 0; unit < stp_all_units_onboard; unit++) {
        l2addr.port = CMIC_PORT(unit);
        bcm_l2_addr_add(unit, &l2addr);
    }

    return 0;
}


/*
*    zhouguis changed this 2005-11-28
*/
void stp_set_mac_address(spantree_t *stp)
{
	char mac[6];
	
	sysSwitchAddrGet(mac);

	sal_memcpy(stp_bridge_mac, mac, 6);
	sal_memcpy((stp->bridge_id + 2), mac, 6);
	return;
}

/*
 * Function:
 *     stp_do_start_mode
 * Purpose:
 *     callback for stack up/down
 * Parameters:
 *     stk_mode - TRUE if stack is up, FALSE if down.
 * Returns:
 *     number of modules
 */
void
stp_do_start_mode(int stk_mode, void *cookie)
{
    spantree_t *stp;

    /* One time initialization, register link scan callback, PMUX */
    if (!stp_sys_initialized) {
        stp_sys_init();
        stp_save_stk_info(stk_mode);
        stp_sys_initialized = 1;
    }

    if (stk_mode) {
        trace(TRACE_STP, TR_LOGIT,
               "\nSTP in stack mode - # CPUs %d, my CPU ID %d\n",
                stp_stk_num_cpu, stp_my_cpuid);
    } else {
/*        debugk(DK_STP,"\nSTP starts in stand alone mode\n");*/
    }

    if (cookie == NULL) {   /* call back from MDP */

        /* change from stacking mode to non-stacking mode, stop RDP */
        if(stp_stack_ready && !stk_mode) {
            rdp_rcv_unregister(BCM_RDP_ID_STP, stp_rcv_rdp_data);
            rdp_cleanup();
        }

        stp_stack_ready = stk_mode;

        /* In stack mode, make sure RDP is started on all modules */
        if (stk_mode) {
            rdp_init(stp_my_cpuid, stp_stk_num_cpu);
            rdp_rcv_register(BCM_RDP_ID_STP, stp_rcv_rdp_data);
        }

        FOR_ALL_STP(stp) {
            stp_deactivate_spantree(stp);
            stp_delete_all_port(stp);

            stp_set_spantree_mac_address(stp, stp_bridge_mac);
            stp_set_mac_address(stp);
            activate_spantree(stp);
            stp_port_add(stp, stk_mode);
        }
    } else {
        stp = (spantree_t *)cookie;
        stp_set_spantree_mac_address(stp, stp_bridge_mac);
        stp_set_mac_address(stp);

        activate_spantree(stp);
        stp_port_add(stp, stk_mode);
    }

}

/*
 * Function:
 *     stp_start
 * Purpose:
 *     Start Spanning Tree (called from CLI command)
 * Parameters:
 *     unit       - Device unit number on which to run mdp
 *     tree_id    - stp instance ID which is VLAN ID
 *     stack_mode - stack mode ?
 *     stk_port - stack port
 */
int
stp_start(stp_id_t tree_id, int stack_mode, int stk_unit, int stk_port)
{
    spantree_t *stp;
    uint8 *stp_name;
    int mdp_state;
    int unit;

    if (!stp_sys_initialized) {
        stp_all_units_onboard = soc_ndev_attached;
    }

    stp_name = sal_alloc(STP_NAME_SIZE, "stp");
    sal_sprintf(stp_name, "STP group %d", tree_id);

    /*
     * all STP instances must agree on the stack mode
     */
    if (stp_instance_q == NULL) {  /* this is the first STP instance */
        stp_stack_unit = stk_unit;
        stp_stack_mode = stack_mode;
        stp_stack_port = stk_port;

        /* create STP instance */
        if (stp_create_instance(&stp, tree_id, stp_name) < 0) {
            sal_free(stp_name);
            return -1;
        }
        stp->l2_age = 300;

        stp_get_common_config_from_db(stp);
        
        for (unit = 0; unit < stp_all_units_onboard; unit++) {
            bcm_l2_age_timer_set(unit, stp->l2_age);
        }
    
        if (!stack_mode) {
            mdp_state_get(&mdp_state);
            if (mdp_state > 0) {
                mdp_get_unit(&stp_stack_unit, &stp_stack_port);
                stp_stack_mode = 1;
                mdp_register_callback(stp_do_start_mode, NULL);
            } else {
                stp_do_start_mode(0, (void*)stp);
            }
        } else {
            mdp_start(stk_unit, stp_stack_port, STK_SL, 1, stp_do_start_mode, NULL);
        }
    } else {
        /* create STP instance */
        if (stp_create_instance(&stp, tree_id, stp_name) < 0) {
            sal_free(stp_name);
            return -1;
        }
        stp->l2_age = 300;

        stp_get_common_config_from_db(stp);        
        for (unit = 0; unit < stp_all_units_onboard; unit++) {
            bcm_l2_age_timer_set(unit, stp->l2_age);
        }
        stp_do_start_mode(stp_stack_mode, (void*)stp);
    }

    return 0;
}

/*
 * Function:
 *     stp_stop
 * Purpose:
 *     Stop Spanning Tree
 */
void
stp_stop(stp_id_t tree_id)
{
    spantree_t *stp;
    int unit;
    bcm_stg_t stg;

    stp = stp_lookup_from_stp_id(tree_id);
    if (stp == NULL) {
        return;
    }

    sal_free(stp->namestring);
    stp_delete_instance(stp);

	stg = search_stg_through_vlan(tree_id);
         for (unit = 0; unit < stp_all_units_onboard; unit++) {
             bcm_stg_destroy(unit, stg);
             }		

  stp_trunk_clean_tree_info(tree_id);
}

/*
 * Function:
 *     stp_set_age_timer
 * Purpose:
 *    Set the STP age timer
 * Parameters:
 *    t - new timer value
 * Returns:
 *     none
 */
void
stp_set_age_timer(stp_id_t tree_id, int t)
{
    spantree_t *stp;
    int unit;

    stp = stp_lookup_from_stp_id(tree_id);
    if (stp == NULL) {
        return;
    }

    /* enable hardware aging of L2 table */
    stp->l2_age = t;
    for (unit = 0; unit < stp_all_units_onboard; unit++) {
        bcm_l2_age_timer_set(unit, t);
    }

    if (stp_stack_ready) {
        stp_send_timer_info(tree_id, t, STP_RDP_AGE_TIMER);
    }
}

/*
 * Function:
 *     stp_set_hello_interval
 * Purpose:
 *     Set STP HELLO interval
 * Parameters:
 *     t - New STP HELLO interval
 * Returns:
 *     none
 */
void
stp_set_hello_interval(stp_id_t tree_id, uint16 t)
{
    spantree_t *stp;

    stp = stp_lookup_from_stp_id(tree_id);
    if (stp == NULL) {
        return;
    }

    set_hello_interval_api(stp, t);

    if (stp_stack_ready) {
        stp_send_timer_info(tree_id, t, STP_RDP_HELLO_TIME);
    }
}

/*
 * Function:
 *     stp_set_max_age
 * Purpose:
 *     Set max age timer value

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -