platform/broadcom/sonic-platform-modules-accton/as7312-54x/utils/accton_as7312_util.py (515 lines of code) (raw):
#!/usr/bin/env python
# Copyright (C) 2016 Accton Networks, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
Usage: %(scriptName)s [options] command object
options:
-h | --help : this help message
-d | --debug : run with debug mode
-f | --force : ignore error during installation or clean
command:
install : install drivers and generate related sysfs nodes
clean : uninstall drivers and remove related sysfs nodes
show : show all systen status
sff : dump SFP eeprom
set : change board setting with fan|led|sfp
"""
import subprocess
import getopt
import sys
import logging
import re
import time
import os
PROJECT_NAME = 'as7312_54x'
version = '0.1.0'
verbose = False
DEBUG = False
ARGS = []
ALL_DEVICE = {}
DEVICE_NO = {
'led': 5,
'fan': 6,
'thermal': 4,
'psu': 2,
'sfp': 54,
}
FORCE = 0
# logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG)
# logging.basicConfig(level=logging.INFO)
if DEBUG == True:
print(sys.argv[0])
print('ARGV :', sys.argv[1:])
def main():
global DEBUG
global ARGS
global FORCE
if len(sys.argv) < 2:
show_help()
(options, ARGS) = getopt.getopt(sys.argv[1:], 'hdf',
['help','debug', 'force'])
if DEBUG == True:
print(options)
print(ARGS)
print(len(sys.argv))
for (opt, arg) in options:
if opt in ('-h', '--help'):
show_help()
elif opt in ('-d', '--debug'):
DEBUG = True
logging.basicConfig(level=logging.INFO)
elif opt in ('-f', '--force'):
FORCE = 1
else:
logging.info('no option')
for arg in ARGS:
if arg == 'install':
do_install()
elif arg == 'clean':
do_uninstall()
elif arg == 'api':
do_sonic_platform_install()
elif arg == 'api_clean':
do_sonic_platform_clean()
elif arg == 'show':
device_traversal()
elif arg == 'sff':
if len(ARGS) != 2:
show_eeprom_help()
elif int(ARGS[1]) == 0 or int(ARGS[1]) > DEVICE_NO['sfp']:
show_eeprom_help()
else:
show_eeprom(ARGS[1])
return
elif arg == 'set':
if len(ARGS) < 3:
show_set_help()
else:
set_device(ARGS[1:])
return
else:
show_help()
return 0
def show_help():
print(__doc__ % {'scriptName': sys.argv[0].split('/')[-1]})
sys.exit(0)
def show_set_help():
cmd = sys.argv[0].split('/')[-1] + ' ' + ARGS[0]
print(cmd + ' [led|sfp|fan]')
print(' use "' + cmd + ' led 0-4 " to set led color')
print(' use "' + cmd + ' fan 0-100" to set fan duty percetage')
print(' use "' + cmd + ' sfp 1-48 {0|1}" to set sfp# tx_disable')
sys.exit(0)
def show_eeprom_help():
cmd = sys.argv[0].split('/')[-1] + ' ' + ARGS[0]
print(' use "' + cmd + ' 1-54 " to dump sfp# eeprom')
sys.exit(0)
def my_log(txt):
if DEBUG == True:
print('[DBG]' + txt)
return
def log_os_system(cmd, show):
logging.info('Run :' + cmd)
(status, output) = subprocess.getstatusoutput(cmd)
my_log(cmd + 'with result:' + str(status))
my_log(' output:' + output)
if status:
logging.info('Failed :' + cmd)
if show:
print('Failed :' + cmd)
return (status, output)
def driver_check():
ret, lsmod = log_os_system("ls /sys/module/*accton*", 0)
logging.info('mods:'+lsmod)
if ret :
return False
else :
return True
kos = [
'modprobe i2c_dev',
'modprobe i2c_mux_pca954x',
'modprobe accton_i2c_cpld',
'modprobe ym2651y',
'modprobe accton_as7312_54x_fan',
'modprobe optoe',
'modprobe accton_as7312_54x_leds',
'modprobe accton_as7312_54x_psu',
]
def driver_install():
global FORCE
log_os_system('depmod', 1)
for i in range(0, len(kos)):
ret = log_os_system(kos[i], 1)
if ret[0] and FORCE == 0:
return status
return 0
def driver_uninstall():
global FORCE
for i in range(0, len(kos)):
rm = kos[-(i + 1)].replace('modprobe', 'modprobe -rq')
rm = rm.replace('insmod', 'rmmod')
lst = rm.split(' ')
if len(lst) > 3:
del lst[3]
rm = ' '.join(lst)
ret = log_os_system(rm, 1)
if ret[0] and FORCE == 0:
return ret[0]
return 0
led_prefix = '/sys/class/leds/accton_' + PROJECT_NAME + '_led::'
hwmon_types = {'led': ['diag', 'fan', 'loc', 'psu1', 'psu2']}
hwmon_nodes = {'led': ['brightness']}
hwmon_prefix = {'led': led_prefix}
i2c_prefix = '/sys/bus/i2c/devices/'
i2c_bus = {
'fan': ['2-0066'],
'thermal': ['3-0048', '3-0049', '3-004a', '3-004b'],
'psu': ['10-0050', '11-0053'],
'sfp': ['-0050'],
}
i2c_nodes = {
'fan': ['present', 'front_speed_rpm', 'rear_speed_rpm'],
'thermal': ['hwmon/hwmon*/temp1_input'],
'psu': ['psu_present ', 'psu_power_good'],
'sfp': ['module_present', 'module_tx_disable'],
}
sfp_map = [18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
68, 69, 70, 71]
qsfp_start = 48
mknod_common = [
'echo as7312_54x_fan 0x66 > /sys/bus/i2c/devices/i2c-2/new_device ',
'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-3/new_device',
'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-3/new_device',
'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-3/new_device',
'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-3/new_device',
'echo as7312_54x_psu1 0x53 > /sys/bus/i2c/devices/i2c-11/new_device',
'echo ym2651 0x5b > /sys/bus/i2c/devices/i2c-11/new_device',
'echo as7312_54x_psu2 0x50 > /sys/bus/i2c/devices/i2c-10/new_device',
'echo ym2651 0x58 > /sys/bus/i2c/devices/i2c-10/new_device',
'echo as7312_54x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-4/new_device',
'echo as7312_54x_cpld2 0x62 > /sys/bus/i2c/devices/i2c-5/new_device',
'echo as7312_54x_cpld3 0x64 > /sys/bus/i2c/devices/i2c-6/new_device']
mknod = [
'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-0/new_device',
'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-0/new_device',
'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-1/new_device',
'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-1/new_device',
'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-1/new_device',
'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-1/new_device',
'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-1/new_device',
'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-1/new_device',
'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device',
'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device',]
mknod = mknod + mknod_common
mknod2 = [
'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-1/new_device',
'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-1/new_device',
'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-0/new_device',
'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-0/new_device',
'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-0/new_device',
'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-0/new_device',
'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-0/new_device',
'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-0/new_device',
'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-0/new_device',
'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-0/new_device',]
mknod2 = mknod2 + mknod_common
def i2c_order_check():
# i2c bus 0 and 1 might be installed in different order.
# Here check if 0x70 is exist @ i2c-1
tmp = "i2cget -y -f 0 0x70"
ret = log_os_system(tmp, 0)
if not ret[0]:
order = 1
else:
order = 0
return order
def device_install():
global FORCE
order = i2c_order_check()
# if 0x70 is not exist @i2c-1, use reversed bus order
if order:
for i in range(0, len(mknod2)):
# for pca954x need times to built new i2c buses
if mknod2[i].find('pca954') != -1:
time.sleep(1)
(status, output) = log_os_system(mknod2[i], 1)
if status:
print(output)
if FORCE == 0:
return status
else:
for i in range(0, len(mknod)):
# for pca954x need times to built new i2c buses
if mknod[i].find('pca954') != -1:
time.sleep(1)
(status, output) = log_os_system(mknod[i], 1)
if status:
print(output)
if FORCE == 0:
return status
# set all pca954x idle_disconnect
cmd = 'echo -2 | tee /sys/bus/i2c/drivers/pca954x/*-00*/idle_state'
status, output = log_os_system(cmd, 1)
if status:
print(output)
if FORCE == 0:
return status
for i in range(0, len(sfp_map)):
if i < qsfp_start:
(status, output) = \
log_os_system('echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-'
+ str(sfp_map[i]) + '/new_device', 1)
else:
(status, output) = \
log_os_system('echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-'
+ str(sfp_map[i]) + '/new_device', 1)
if status:
print(output)
if FORCE == 0:
return status
return
def device_uninstall():
global FORCE
for i in range(0, len(sfp_map)):
target = '/sys/bus/i2c/devices/i2c-' + str(sfp_map[i]) \
+ '/delete_device'
(status, output) = log_os_system('echo 0x50 > ' + target, 1)
if status:
print(output)
if FORCE == 0:
return status
order = i2c_order_check()
if order :
nodelist = mknod2
else:
nodelist = mknod
for i in range(len(nodelist)):
target = nodelist[-(i + 1)]
temp = target.split()
del temp[1]
temp[-1] = temp[-1].replace('new_device', 'delete_device')
(status, output) = log_os_system(' '.join(temp), 1)
if status:
print(output)
if FORCE == 0:
return status
return
def system_ready():
if driver_check() is False:
return False
if not device_exist():
return False
return True
PLATFORM_ROOT_PATH = '/usr/share/sonic/device'
PLATFORM_API2_WHL_FILE_PY3 ='sonic_platform-1.0-py3-none-any.whl'
def do_sonic_platform_install():
device_path = "{}{}{}{}".format(PLATFORM_ROOT_PATH, '/x86_64-accton_', PROJECT_NAME, '-r0')
SONIC_PLATFORM_BSP_WHL_PKG_PY3 = "/".join([device_path, PLATFORM_API2_WHL_FILE_PY3])
#Check API2.0 on py whl file
status, output = log_os_system("pip3 show sonic-platform > /dev/null 2>&1", 0)
if status:
if os.path.exists(SONIC_PLATFORM_BSP_WHL_PKG_PY3):
status, output = log_os_system("pip3 install "+ SONIC_PLATFORM_BSP_WHL_PKG_PY3, 1)
if status:
print("Error: Failed to install {}".format(PLATFORM_API2_WHL_FILE_PY3))
return status
else:
print("Successfully installed {} package".format(PLATFORM_API2_WHL_FILE_PY3))
else:
print(('{} is not found'.format(PLATFORM_API2_WHL_FILE_PY3)))
else:
print(('{} has installed'.format(PLATFORM_API2_WHL_FILE_PY3)))
return
def do_sonic_platform_clean():
status, output = log_os_system("pip3 show sonic-platform > /dev/null 2>&1", 0)
if status:
print(('{} does not install, not need to uninstall'.format(PLATFORM_API2_WHL_FILE_PY3)))
else:
status, output = log_os_system("pip3 uninstall sonic-platform -y", 0)
if status:
print(('Error: Failed to uninstall {}'.format(PLATFORM_API2_WHL_FILE_PY3)))
return status
else:
print(('{} is uninstalled'.format(PLATFORM_API2_WHL_FILE_PY3)))
return
def do_install():
print('Checking system....')
if driver_check() is False:
print('No driver, installing....')
status = driver_install()
if status:
if FORCE == 0:
return status
else:
print(PROJECT_NAME.upper() + ' drivers detected....')
if not device_exist():
print('No device, installing....')
status = device_install()
if status:
if FORCE == 0:
return status
else:
print(PROJECT_NAME.upper() + ' devices detected....')
do_sonic_platform_install()
return
def do_uninstall():
print('Checking system....')
if not device_exist():
print(PROJECT_NAME.upper() + ' has no device installed....')
else:
print('Removing device....')
status = device_uninstall()
if status and FORCE == 0:
return status
if driver_check() is False:
print(PROJECT_NAME.upper() + ' has no driver installed....')
else:
print('Removing installed driver....')
status = driver_uninstall()
if status and FORCE == 0:
return status
do_sonic_platform_clean()
return None
def devices_info():
global DEVICE_NO
global ALL_DEVICE
global i2c_bus, hwmon_types
for key in DEVICE_NO:
ALL_DEVICE[key] = {}
for i in range(0, DEVICE_NO[key]):
ALL_DEVICE[key][key + str(i + 1)] = []
for key in i2c_bus:
buses = i2c_bus[key]
nodes = i2c_nodes[key]
for i in range(0, len(buses)):
for j in range(0, len(nodes)):
if 'fan' == key:
for k in range(0, DEVICE_NO[key]):
node = key + str(k + 1)
path = i2c_prefix + buses[i] + '/fan' + str(k
+ 1) + '_' + nodes[j]
my_log(node + ': ' + path)
ALL_DEVICE[key][node].append(path)
elif 'sfp' == key:
for k in range(0, DEVICE_NO[key]):
if k in range(24) or k in range(48, 52):
fmt = i2c_prefix + '5-0062/{0}_{1}'
else:
fmt = i2c_prefix + '6-0064/{0}_{1}'
node = key + str(k + 1)
path = fmt.format(nodes[j], k + 1)
my_log(node + ': ' + path)
ALL_DEVICE[key][node].append(path)
else:
node = key + str(i + 1)
path = i2c_prefix + buses[i] + '/' + nodes[j]
my_log(node + ': ' + path)
ALL_DEVICE[key][node].append(path)
for key in hwmon_types:
itypes = hwmon_types[key]
nodes = hwmon_nodes[key]
for i in range(0, len(itypes)):
for j in range(0, len(nodes)):
node = key + '_' + itypes[i]
path = hwmon_prefix[key] + itypes[i] + '/' + nodes[j]
my_log(node + ': ' + path)
ALL_DEVICE[key][key + str(i + 1)].append(path)
# show dict all in the order
if DEBUG == True:
for i in sorted(ALL_DEVICE.keys()):
print(i + ': ')
for j in sorted(ALL_DEVICE[i].keys()):
print(' ' + j)
for k in ALL_DEVICE[i][j]:
print(' ' + ' ' + k)
return
def show_eeprom(index):
if system_ready() is False:
print('Systems not ready.')
print('Please install first!')
return
if len(ALL_DEVICE) == 0:
devices_info()
node = ALL_DEVICE['sfp']['sfp' + str(index)][0]
node = node.replace(node.split('/')[-1], 'sfp_eeprom')
# check if got hexdump command in current environment
(ret, log) = log_os_system('which hexdump', 0)
(ret, log2) = log_os_system('which busybox hexdump', 0)
if log:
hex_cmd = 'hexdump'
elif log2:
hex_cmd = ' busybox hexdump'
else:
log = 'Failed : no hexdump cmd!!'
logging.info(log)
print(log)
return 1
print(node + ':')
(ret, log) = log_os_system('cat ' + node + '| ' + hex_cmd + ' -C',
1)
if ret == 0:
print(log)
else:
print( '**********device no found**********')
return
def set_device(args):
global DEVICE_NO
global ALL_DEVICE
if system_ready() is False:
print('System is not ready.')
print('Please install first!')
return
if not ALL_DEVICE:
devices_info()
if args[0] == 'led':
if int(args[1]) > 4:
show_set_help()
return
# print ALL_DEVICE['led']
for i in range(0, len(ALL_DEVICE['led'])):
for k in ALL_DEVICE['led']['led' + str(i + 1)]:
ret = log_os_system('echo ' + args[1] + ' >' + k, 1)
if ret[0]:
return ret[0]
elif args[0] == 'fan':
if int(args[1]) > 100:
show_set_help()
return
# print ALL_DEVICE['fan']
# fan1~6 is all fine, all fan share same setting
node = ALL_DEVICE['fan']['fan1'][0]
node = node.replace(node.split('/')[-1],
'fan_duty_cycle_percentage')
(ret, log) = log_os_system('cat ' + node, 1)
if ret == 0:
print('Previous fan duty: ' + log.strip() + '%')
ret = log_os_system('echo ' + args[1] + ' >' + node, 1)
if ret[0] == 0:
print('Current fan duty: ' + args[1] + '%')
return ret
elif args[0] == 'sfp':
if int(args[1]) > qsfp_start or int(args[1]) == 0:
show_set_help()
return
if len(args) < 2:
show_set_help()
return
if int(args[2]) > 1:
show_set_help()
return
# print ALL_DEVICE[args[0]]
for i in range(len(ALL_DEVICE[args[0]])):
for j in ALL_DEVICE[args[0]][args[0] + str(args[1])]:
if j.find('tx_disable') != -1:
ret = log_os_system('echo ' + args[2] + ' >' + j, 1)
if ret[0]:
return ret[0]
return
# get digits inside a string.
# Ex: get 31 from "sfp31"
def get_value(i):
digit = re.findall('\d+', i)
return int(digit[0])
def device_traversal():
if system_ready() is False:
print("System is not ready.")
print('Please install first!')
return
if not ALL_DEVICE:
devices_info()
for i in sorted(ALL_DEVICE.keys()):
print('============================================')
print(i.upper() + ': ')
print('============================================')
for j in sorted(list(ALL_DEVICE[i].keys()), key=get_value):
print(' ' + j + ':', end=' ')
for k in ALL_DEVICE[i][j]:
(ret, log) = log_os_system('cat ' + k, 0)
func = k.split('/')[-1].strip()
func = re.sub(j + '_', '', func, 1)
func = re.sub(i.lower() + '_', '', func, 1)
if ret == 0:
print(func + '=' + log + ' ', end=' ')
else:
print(func + '=' + 'X' + ' ', end=' ')
print()
print('----------------------------------------------------------------')
print()
return
def device_exist():
ret1 = log_os_system('ls ' + i2c_prefix + '*0070', 0)
ret2 = log_os_system('ls ' + i2c_prefix + 'i2c-2', 0)
return not (ret1[0] or ret2[0])
if __name__ == '__main__':
main()