#!/bin/sh
#
#
#    Copyright (c) 2011-2012, 2014 Brocade Communications, Inc.
#    All rights reserved.
#
#    Description:
#      serdes_show [n] - show current SERDES parameters for port(s) n,
#      on Condor3 ASIC, using information from the portregshow command
#
#
#      Condor3 has a large set of registers per port.
#      Totally four groups of serdes settings can be pre-configured.
#      In C3, configuration group 1 to 4 are pre-configured for 2G, 4G, 8G and
#      16G respectively.
#
#      "serdes_show" can only show one group of settings that is currently used.
#      To know which group of serdes settings it is pointing to, the txcfg/rxcfg
#      registers should be checked and the mappings are as below.
#
#      txcfg register bits 12:11
#      00: bits 8:0 define configuration 0 / 2G
#      01: bits 8:0 define configuration 1 / 4G
#      10: bits 8:0 define configuration 2 / 8G
#      11: bits 8:0 define configuration 3 / 16G
#
#      rxcfg register bits 12:11
#      00: bits 8:0 define configuration 0 / 2G
#      01: bits 8:0 define configuration 1 / 4G
#      10: bits 8:0 define configuration 2 / 8G
#      11: bits 8:0 define configuration 3 / 16G
#
#      To make it user friendly, the current speed is shown at the same time.
#


PREGSHOW="/fabos/link_bin/portregshow"
ECHO="/bin/echo"
GREP="/fabos/link_bin/grep"
AWK="/bin/awk"
TXCFGMODE="hsstx_cfg_mode"
TXDRV="hsstx_drv_mode_ct_tune3"
TXAMP="hsstx_amp_tunec"
TXTAP0="hsstx_tap0_coeff_tune8"
TXTAP1="hsstx_tap1_coeff_tune9"
TXTAP2="hsstx_tap2_coeff_tunea"
TXTAP0APP="hsstx_tap0_coeff_app"
TXTAP1APP="hsstx_tap1_coeff_app"
TXTAP2APP="hsstx_tap2_coeff_app"
TXPOL="hsstx_pol_tuned_inv"
RXCFGMODE="hssrx_cfg_mode_tune0"
TXCOEFCTRL="hsstx_coeff_ctl"
HEADER="port speed eqmode drv  tap0 tap1 tap2 amp  tap0app tap1app tap2app"
FORMAT="%2d   %3.3s   %6.6s %04x %04x %04x %04x %04x  %04x    %04x    %04x\n"

#show serdes settings of one port
function show_port {
#cache the hss register dump
hssdump=`$PREGSHOW $1 | $GREP "hss[tr]x"`

if [[ -n "$hssdump" ]]
then
  txcfgmode=0x`$ECHO "$hssdump" | $GREP $TXCFGMODE | $AWK '{print $3}'`
  txdrvmoce=0x`$ECHO "$hssdump" | $GREP $TXDRV | $AWK '{print $6}'`
  tap0=`$ECHO "$hssdump" | $GREP $TXTAP0`
  tap1=`$ECHO "$hssdump" | $GREP $TXTAP1`
  tap2=`$ECHO "$hssdump" | $GREP $TXTAP2`
  tap0app=`$ECHO "$hssdump" | $GREP $TXTAP0APP`
  tap1app=`$ECHO "$hssdump" | $GREP $TXTAP1APP`
  tap2app=`$ECHO "$hssdump" | $GREP $TXTAP2APP`
  cfgtap0=0x`$ECHO "$tap0" | $AWK '{print $3}'`
  cfgtap1=0x`$ECHO "$tap1" | $AWK '{print $6}'`
  cfgtap2=0x`$ECHO "$tap2" | $AWK '{print $3}'`
  apptap0=0x`$ECHO "$tap0app" | $AWK '{print $3}'`
  apptap1=0x`$ECHO "$tap1app" | $AWK '{print $6}'`
  apptap2=0x`$ECHO "$tap2app" | $AWK '{print $3}'`
  txamp=0x`$ECHO "$hssdump" | $GREP $TXAMP | $AWK '{print $6}'`
  txpol=0x`$ECHO "$hssdump" | $GREP $TXPOL | $AWK '{print $3}'`
  rxcfgmode=0x`$ECHO "$hssdump" | $GREP $RXCFGMODE | $AWK '{print $3}'`
  txcoeffctl=0x`$ECHO "$hssdump" | $GREP $TXCOEFCTRL | $AWK '{print $3}'`

  #extract the configuration group pointer
  let "cfgmodesel=($txcfgmode >> 11) & 0x3"

  #only one configuration group of serdes settings is valid
  case $cfgmodesel in
	0)  speed="2G";;
	1)  speed="4G";;
	2)  speed="8G";;
	3)  speed="16G";;
	*)  speed="N/A"
  esac

  #equalization mode
  let "eqmode=($txcoeffctl >> 4) & 0x1"
  if [[ $eqmode -eq 0x1 ]]
  then
	mode="KR"
  else
	mode="Non-KR"
  fi

  #print the serdes settings
  printf "$FORMAT" $1 $speed $mode $txdrvmoce $cfgtap0 $cfgtap1 $cfgtap2 $txamp\
			$apptap0 $apptap1 $apptap2
fi
}

function last_port_number_from_switchshow {
 # extract last port number from the last line of switchshow
 # this assumes a pizza box -- on a modular system the port # is the 3rd param
 N=$2
}

# print the heading
echo "$HEADER"

# If no command line arguments, do all ports
if [ $# = 0 ]
then
	last_port_number_from_switchshow `switchshow | tail -1`
	for ((i=0; i<=$N; i++))
	do
		show_port $i
	done
else
	for i in $*
	do
		show_port $i
	done
fi
