58db7f17a7
* [device]: Modify SFPUtil for inventec-d7032 [device]: Add front panel led support for Inventec-d7032 [platform]: Add transceiver monitor daemon for Inventec-d7032 and Inventec-d7054 * [device] follow new porting guide to have broadcom config under device folder * remove license
315 lines
10 KiB
Python
Executable File
315 lines
10 KiB
Python
Executable File
#!/usr/bin/env python
|
|
#
|
|
|
|
import os
|
|
import time
|
|
import syslog
|
|
import re
|
|
from sonic_sfp.bcmshell import bcmshell
|
|
|
|
# =====================================================================
|
|
# global variable init
|
|
# =====================================================================
|
|
|
|
# define data ram address
|
|
PORT_DATA_OFFSET_ADDR = 0xA0
|
|
PORT_DATA_START_ADDR = 0xF2
|
|
TOTAL_SCAN_BITS_ADDR = 0xF4
|
|
SYNC_START_LEN_ADDR = 0xF6
|
|
SYNC_STOP_LEN_ADDR = 0xF8
|
|
# bit streaming rule for CPLD decode
|
|
TOTAL_SCAN_BITS = None
|
|
SYNC_S = None
|
|
SYNC_P = None
|
|
# define port data for bit streaming
|
|
BIT_LINK = None
|
|
BIT_FAULT = None
|
|
BIT_TX = None
|
|
BIT_RX = None
|
|
BIT_SPEED0 = None
|
|
BIT_SPEED1 = None
|
|
# define port speed
|
|
SPEED_100G = 100
|
|
SPEED_40G = 40
|
|
SPEED_25G = 25
|
|
SPEED_10G = 10
|
|
# the amount of LED processor
|
|
AMOUNT_LED_UP = None
|
|
# define board type
|
|
INV_REDWOOD = "SONiC-Inventec-d7032-100"
|
|
INV_CYPRESS = "SONiC-Inventec-d7054"
|
|
INV_SEQUOIA = ""
|
|
BOARD_TPYE = ""
|
|
EAGLE_CORE = []
|
|
|
|
PORT_LIST = []
|
|
|
|
# port status that is auto update by chip in data ram
|
|
# there are two byte to indicate each port status
|
|
'''
|
|
RX equ 0x0 ; received packet
|
|
TX equ 0x1 ; transmitted packet
|
|
COLL equ 0x2 ; collision indicator
|
|
SPEED_C equ 0x3 ; 100 Mbps
|
|
SPEED_M equ 0x4 ; 1000 Mbps
|
|
DUPLEX equ 0x5 ; half/full duplex
|
|
FLOW equ 0x6 ; flow control capable
|
|
LINKUP equ 0x7 ; link down/up status
|
|
LINKEN equ 0x8 ; link disabled/enabled status
|
|
ZERO equ 0xE ; always 0
|
|
ONE equ 0xF ; always 1
|
|
'''
|
|
STATUS_ENABLE = 1<<0
|
|
STATUS_RX = 1<<0
|
|
STATUS_TX = 1<<1
|
|
|
|
# object is to execute bcm shell command
|
|
BCM_SHELL = None
|
|
|
|
|
|
|
|
# =====================================================================
|
|
# class object
|
|
# =====================================================================
|
|
class Led():
|
|
|
|
up = None
|
|
pfw = None
|
|
|
|
def __init__(self, led_number, program_fw):
|
|
self.up = led_number
|
|
self.pfw = program_fw
|
|
|
|
def led_start(self):
|
|
BCM_SHELL.cmd("led {0} start".format(self.up))
|
|
syslog.syslog(syslog.LOG_INFO, "Start Led({0})".format(self.up))
|
|
|
|
def led_stop(self):
|
|
BCM_SHELL.cmd("led {0} stop".format(self.up))
|
|
syslog.syslog(syslog.LOG_INFO, "Stop Led({0})".format(self.up))
|
|
|
|
def load_prog(self):
|
|
BCM_SHELL.cmd("led {0} prog {1}".format(self.up, self.pfw))
|
|
syslog.syslog(syslog.LOG_INFO, "Load Led({0}) program firmware".format(self.up))
|
|
|
|
def write_port_data(self, addr, data):
|
|
BCM_SHELL.cmd("setreg CMIC_LEDUP{0}_DATA_RAM({1}) {2}".format(self.up, addr, data))
|
|
#syslog.syslog(syslog.LOG_DEBUG, "Write Led({0}) data_ram({1}): {2}".format(self.up, addr, data))
|
|
|
|
def read_data_ram(self, offset):
|
|
return_string = BCM_SHELL.run("getreg CMIC_LEDUP{0}_DATA_RAM({1})".format(self.up, offset))
|
|
for line in return_string.split("\n"):
|
|
re_obj = re.search(r"\<DATA\=(?P<data>.+)\>",line)
|
|
if re_obj is not None:
|
|
#syslog.syslog(syslog.LOG_DEBUG, "Read Led({0}) data_ram({1}): {2}".format(self.up, offset, re_obj.group("data")))
|
|
return int(re_obj.group("data"), 16)
|
|
|
|
return None
|
|
|
|
|
|
# =====================================================================
|
|
# Function
|
|
# =====================================================================
|
|
def _remap_registers():
|
|
|
|
fp = open('/usr/share/sonic/device/x86_64-inventec_d7032q28b-r0/led_proc_init.soc', "r")
|
|
content = fp.readlines()
|
|
fp.close()
|
|
err = False
|
|
|
|
for line in content:
|
|
try:
|
|
BCM_SHELL.cmd(line.rstrip())
|
|
except Exception, e:
|
|
err = True
|
|
syslog.syslog(syslog.LOG_ERR, "remap register abnormal: {0}".format(str(e)))
|
|
|
|
if not err:
|
|
pass
|
|
#syslog.syslog(syslog.LOG_DEBUG, "remap Led registers successfully")
|
|
|
|
|
|
|
|
def _update_port_list():
|
|
|
|
global PORT_LIST
|
|
PORT_LIST = []
|
|
number = 0
|
|
count = 0
|
|
|
|
content = BCM_SHELL.run("ps")
|
|
for line in content.split("\n"):
|
|
re_obj = re.search(r"(?P<port_name>(xe|ce)\d+)\(\s*(?P<bcm_id>\d+)\)\s+(?P<link>(up|down|!ena)).+\s+(?P<speed>\d+)G",line)
|
|
if re_obj is not None:
|
|
if int(re_obj.group("bcm_id")) not in EAGLE_CORE:
|
|
PORT_LIST.append({"port_id":number, "name":re_obj.group("port_name"), "bcm_id":int(re_obj.group("bcm_id")), "link":re_obj.group("link"), "speed":int(re_obj.group("speed"))})
|
|
number += 1
|
|
|
|
content = BCM_SHELL.run("led status")
|
|
for line in content.split("\n"):
|
|
re_obj = re.search(r"(?P<bcm_id>\d+).+(?P<led_up>\d)\:(?P<offset>\d+)",line)
|
|
if re_obj is not None:
|
|
if int(re_obj.group("bcm_id")) not in EAGLE_CORE:
|
|
PORT_LIST[count]["led_up"] = int(re_obj.group("led_up"))
|
|
PORT_LIST[count]["offset"] = int(re_obj.group("offset"))
|
|
count += 1
|
|
|
|
if number is not count:
|
|
PORT_LIST = []
|
|
syslog.syslog(syslog.LOG_ERR, "The amount of port is not match")
|
|
else:
|
|
pass
|
|
#syslog.syslog(syslog.LOG_DEBUG, "update port list successfully")
|
|
|
|
|
|
|
|
def _lookup_led_index(p):
|
|
|
|
index = 0
|
|
for port in PORT_LIST:
|
|
if p["bcm_id"] == port["bcm_id"]:
|
|
break
|
|
if p["led_up"] == port["led_up"]:
|
|
index += 1
|
|
return index + PORT_DATA_OFFSET_ADDR
|
|
|
|
|
|
|
|
def _led_init():
|
|
|
|
global BOARD_TPYE
|
|
global AMOUNT_LED_UP
|
|
global BIT_LINK
|
|
global BIT_FAULT
|
|
global BIT_TX
|
|
global BIT_RX
|
|
global BIT_SPEED0
|
|
global BIT_SPEED1
|
|
global EAGLE_CORE
|
|
global TOTAL_SCAN_BITS
|
|
global SYNC_S
|
|
global SYNC_P
|
|
|
|
cmd = "uname -n"
|
|
platform = os.popen(cmd).read()
|
|
|
|
if platform.rstrip() == INV_REDWOOD:
|
|
BOARD_TPYE = "inventec_d7032q28b"
|
|
AMOUNT_LED_UP = 2
|
|
BIT_RX = 1<<0 #0x01
|
|
BIT_TX = 1<<1 #0x02
|
|
BIT_SPEED0 = 1<<3 #0x08
|
|
BIT_SPEED1 = 1<<4 #0x10
|
|
BIT_FAULT = 1<<6 #0x40
|
|
BIT_LINK = 1<<7 #0x80
|
|
TOTAL_SCAN_BITS = 32*1*4
|
|
SYNC_S = 15
|
|
SYNC_P = 3
|
|
EAGLE_CORE = [66, 100]
|
|
_remap_registers()
|
|
|
|
elif platform.rstrip() == INV_CYPRESS:
|
|
BOARD_TPYE = "inventec_d7054q28b"
|
|
AMOUNT_LED_UP = 2
|
|
BIT_LINK = 1<<0 #0x01
|
|
BIT_FAULT = 1<<1 #0x02
|
|
BIT_SPEED0 = 1<<2 #0x04
|
|
EAGLE_CORE = [66, 100]
|
|
|
|
elif platform.rstrip() == INV_SEQUOIA:
|
|
BOARD_TPYE = "inventec_d7264q28b"
|
|
AMOUNT_LED_UP = 4
|
|
|
|
else:
|
|
BOARD_TPYE = "not found"
|
|
|
|
syslog.syslog(syslog.LOG_INFO, "Device: {0}".format(BOARD_TPYE))
|
|
#syslog.syslog(syslog.LOG_DEBUG, "led_amount: {0}".format(AMOUNT_LED_UP))
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
waitSyncd = True
|
|
retryCount = 0
|
|
syslog.openlog("led_proc", syslog.LOG_PID, facility=syslog.LOG_DAEMON)
|
|
|
|
while waitSyncd:
|
|
try:
|
|
BCM_SHELL = bcmshell()
|
|
waitSyncd = False
|
|
except Exception, e:
|
|
syslog.syslog(syslog.LOG_WARNING, "{0}, Retry times({1})".format(str(e),retryCount))
|
|
retryCount += 1
|
|
time.sleep(5)
|
|
|
|
|
|
_led_init()
|
|
led_obj = []
|
|
for idx in range(AMOUNT_LED_UP):
|
|
led_obj.append(Led(idx, ""))
|
|
#syslog.syslog(syslog.LOG_DEBUG, "create object led({0}) successfully".format(idx))
|
|
|
|
if BOARD_TPYE == "inventec_d7032q28b":
|
|
led_obj[idx].write_port_data(PORT_DATA_START_ADDR, PORT_DATA_OFFSET_ADDR)
|
|
led_obj[idx].write_port_data(TOTAL_SCAN_BITS_ADDR, TOTAL_SCAN_BITS)
|
|
led_obj[idx].write_port_data(SYNC_START_LEN_ADDR, SYNC_S)
|
|
led_obj[idx].write_port_data(SYNC_STOP_LEN_ADDR, SYNC_P)
|
|
|
|
|
|
reset_sec = 2
|
|
count_down = 0
|
|
queue_active = []
|
|
port_data = None
|
|
while True:
|
|
if count_down == 0:
|
|
queue_active = []
|
|
_update_port_list()
|
|
for port in PORT_LIST:
|
|
if port["link"] == "up":
|
|
queue_active.append(port)
|
|
else:
|
|
port_data = 0
|
|
# redwood bit streaming for CPLD decode is only use led up0
|
|
led_obj[0].write_port_data(PORT_DATA_OFFSET_ADDR + port["port_id"], port_data)
|
|
count_down = reset_sec
|
|
else:
|
|
for port in queue_active:
|
|
port_data = 0
|
|
|
|
if BOARD_TPYE == "inventec_d7032q28b":
|
|
port_data |= BIT_LINK
|
|
addr = 2*(port["offset"]-1)
|
|
byte1 = led_obj[port["led_up"]].read_data_ram(addr)
|
|
byte2 = led_obj[port["led_up"]].read_data_ram(addr+1)
|
|
if byte1&STATUS_RX:
|
|
port_data |= BIT_RX
|
|
if byte1&STATUS_TX:
|
|
port_data |= BIT_TX
|
|
if port["speed"] == SPEED_100G:
|
|
port_data |= BIT_SPEED0
|
|
port_data |= BIT_SPEED1
|
|
elif port["speed"] == SPEED_40G:
|
|
port_data |= BIT_SPEED1
|
|
elif port["speed"] == SPEED_25G:
|
|
port_data |= BIT_SPEED0
|
|
else:
|
|
pass
|
|
|
|
# redwood bit streaming for CPLD decode is only use led up0
|
|
led_obj[0].write_port_data(PORT_DATA_OFFSET_ADDR + port["port_id"], port_data)
|
|
continue
|
|
|
|
elif BOARD_TPYE == "inventec_d7054q28b":
|
|
if port["speed"] != SPEED_100G and port["speed"] != SPEED_25G:
|
|
port_data |= BIT_SPEED0
|
|
|
|
led_index = _lookup_led_index(port)
|
|
led_obj[port["led_up"]].write_port_data(led_index, port_data)
|
|
|
|
time.sleep(0.5)
|
|
count_down -= 1
|
|
|
|
syslog.closelog()
|
|
|