#! /pkg/bin/ksh
#--------------------------------------------------------------
# show_tech_bfdoff_pd  -- BFD Offload show tech-support utils
#
# Copyright (c) 2015-2019, 2023 by cisco Systems, Inc.
# All rights reserved.
#-------------------------------------------------------------

. /pkg/bin/show_tech_main_fragment

num_j2="0"
gen2_asic="0"
bfdhwoff_pkt_sock_drops="0"

#     BCM88675 (Jericho),    Also BCM88670
#     BCM88680 (JerichoPlus) 
#     BCM88370 (Qumran-MX),  Also BCM88375
#     BCM88470 (Qumran-AX)
#     BCM88690 (Jericho-2)
#     BCM88485 (Qumran-2A)
#     BCM88820 (Q2C)
#     BCM88850 (J2C+)
#     BCM88802 (J2C)
#     BCM88470 (QAX)
#     BCM88272 (QUX)
#     We need to revise this logic in the future:
#     1. loop through all possible Dune chip type, find out how many each type(s)
#        are present on the board
#     2. Instead of blindly repeat each cli MAX_NPU number of times, use result
#        from step 1 to dynamically determine how many npus are present
#     3. Asic specific commands(other than J2)
get_brcm_npu_type() {
    brcm_vendor_id=14e4
    brcm_j2_dev_id=869      # 869X
    brcm_qumran_2a_dev_id=8485 # Quamran 2A
    brcm_qumram_2c_dev_id=8820 # Q2C
    brcm_j2c_plus_dev_id=8850 # J2C+
    brcm_j2c_dev_id=8802 # J2C
    brcm_qax_dev_id=8470 # QAX
    brcm_qux_dev_id=8272 # QUX
    num_j2=$(lspci -nd ${brcm_vendor_id}: | grep -oc ${brcm_j2_dev_id})    
    num_qumran_2a=$(lspci -nd ${brcm_vendor_id}: | grep -oc ${brcm_qumran_2a_dev_id})
    num_qumram_2c=$(lspci -nd ${brcm_vendor_id}: | grep -oc ${brcm_qumram_2c_dev_id})
    num_j2c_plus=$(lspci -nd ${brcm_vendor_id}: | grep -oc ${brcm_j2c_plus_dev_id})
    num_j2c=$(lspci -nd ${brcm_vendor_id}: | grep -oc ${brcm_j2c_dev_id})
    num_qax=$(lspci -nd ${brcm_vendor_id}: | grep -oc ${brcm_qax_dev_id})
    num_qux=$(lspci -nd ${brcm_vendor_id}: | grep -oc ${brcm_qux_dev_id})
    if [ ${num_j2} -gt 0 ] || [ ${num_qumran_2a} -gt 0 ] || [ ${num_qumram_2c} -gt 0 ] || [ ${num_j2c_plus} -gt 0 ] || [ ${num_j2c} -gt 0 ];  then
        gen2_asic=1	
    fi
}

# *************************************************
# BFD related diagshell commands for Jericho chips 
# *************************************************
get_brcm_npu_type

# *******************************************
# BFD Punt packet losses between J2 and CPU
# *******************************************
show_bfdhwoff_pkt_sock_drops() {
    bfd_pid=`pidof bfd_agent`
    numre='^[0-9]+$'
    if [[ $bfd_pid =~ $numre ]]; then
        sock_inode=`lsof -p ${bfd_pid} | grep PACKET | awk '{print $8}'`
        bfdhwoff_pkt_sock_drops=`cat /proc/${bfd_pid}/net/packet | grep ${sock_inode} | awk '{print $14}'`
        echo "BFD-HWOFF Packet Sock Drops: ${bfdhwoff_pkt_sock_drops}"
        print_heading "BFD-HWOFF Packet Sock Drops: ${bfdhwoff_pkt_sock_drops}"
     fi
}

#
# All diagshell commands follow here
#
cmd_index=1
if [ ${gen2_asic} -gt 0 ];  then
    #
    # J2 only diagshell commands
    #
    # "diag count g " needs to run twice since the count is a running count
    dshell_cmd[$cmd_index]="getreg oamp_cpuport"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="TM INGress Queue NON"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="oam oamp counter"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="tm egr cong"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="getreg OAMP_VALIDITY_CHECK_STICKY"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="setreg OAMP_VALIDITY_CHECK_STICKY 0"
    ((cmd_index++))

    #show-tech framework allows only uniq command. as a work-around, using different
    #formats for same command
    dshell_cmd[$cmd_index]="get OAMP_VALIDITY_CHECK_STICKY"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="oam bfdendpoint"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="oam oamp status"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="dbal table dump table=OAMP_RMEP_DB"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="dbal table dump table=OAMP_MEP_DB"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="dbal table dump table=L2_PUNT"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="TM INGress Queue NON_empty"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="oam oamp counter"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="tm egr congestion"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="d OAMP_CLS_TRAP_CODE_TCAM"
    ((cmd_index++))

else
    #
    # J only diagshell commands
    #
    dshell_cmd[$cmd_index]="TM INGress Queue NON"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="diag egr"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="diag cosq voq congestion"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="diag oam count oamp"
    ((cmd_index++))

    if [ ${num_qax} -gt 0 ] || [ ${num_qux} -gt 0 ];  then
        dshell_cmd[$cmd_index]="d OAMP_CLS_TRAP_CODE_TCAM"
        ((cmd_index++))
    else
        dshell_cmd[$cmd_index]="g OAMP_RX_TRAP_CODES"
        ((cmd_index++))
    fi

    dshell_cmd[$cmd_index]="getreg oamp_cpuport"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="get OAMP_VALIDITY_CHECK_STICKY"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="diag oam endpoints"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="dump disable_cache chg OAMP_MEP_DB"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="dump disable_cache chg OAMP_MEP_DB_BFD_ON_IPV4_MULTI_HOP"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="dump disable_cache chg oamp_rmep_db"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="d IHP_VRID_MY_MAC_TCAM"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="TM INGress Queue NON_empty"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="diag egr_congestion"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="diag cos voq congestion"
    ((cmd_index++))

    dshell_cmd[$cmd_index]="diag oam counters oamp"
    ((cmd_index++))
fi

cmd_index=1
if [ ${num_j2} -gt 0 ]; then
    i=0
    while [[ $i -lt $num_j2 ]]; do
        for d in "${!dshell_cmd[@]}"; do
            dcmd=$(eval "echo ${dshell_cmd[d]} | sed 's/ /-/g'")
            bfdpd_rplc_show_exec[$cmd_index]="show controllers fia diagshell $i ${dshell_cmd[d]} location \$location"
            bfdpd_rplc_show__ksh[$cmd_index]="fia_driver_show -c $dcmd -u $i "
            ((cmd_index++))
         done
         ((i++))
    done
else
    for d in "${!dshell_cmd[@]}"; do
        dcmd=$(eval "echo ${dshell_cmd[d]} | sed 's/ /-/g'")
        bfdpd_rplc_show_exec[$cmd_index]="show controllers fia diagshell 0 ${dshell_cmd[d]} location \$location"
        bfdpd_rplc_show__ksh[$cmd_index]="fia_driver_show -c $dcmd -u 0 -n $1"
        ((cmd_index++))
     done
fi

bfdpd_rplc_show_exec[$cmd_index]=''
bfdpd_rplc_show__ksh[$cmd_index]=''

#############################################################################
# Script

display_bfd_hwoff_pd() {
    print_heading "show tech-support bfd-pd-dnx"
   if [ "$__cardtype" != "SYS" ]; then
       case "$__cardtype" in

       "LC")
           exec_commands bfdpd_rplc_show
           show_bfdhwoff_pkt_sock_drops
           ;;

       esac
   fi
}
