platform/broadcom/sonic-platform-modules-accton/as7716-32x/utils/accton_as7716_util.py (495 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 from sonic_py_common.general import getstatusoutput_noshell PROJECT_NAME = 'as7716_32x' version = '0.0.1' verbose = False DEBUG = False args = [] ALL_DEVICE = {} DEVICE_NO = {'led':5, 'fan1':1, 'fan2':1,'fan3':1,'fan4':1,'fan5':1,'thermal':3, 'psu':2, 'sfp':54} led_prefix ='/sys/devices/platform/as7716_32x_led/leds/accton_'+PROJECT_NAME+'_led::' fan_prefix ='/sys/devices/platform/as7716_32x_' hwmon_types = {'led': ['diag','fan','loc','psu1','psu2'], 'fan1': ['fan'], 'fan2': ['fan'], 'fan3': ['fan'], 'fan4': ['fan'], 'fan5': ['fan'], } hwmon_nodes = {'led': ['brightness'] , 'fan1': ['fan_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'], 'fan2': ['fan_duty_cycle_percentage','fan2_fault', 'fan2_speed_rpm', 'fan2_direction', 'fanr2_fault', 'fanr2_speed_rpm'], 'fan3': ['fan_duty_cycle_percentage','fan3_fault', 'fan3_speed_rpm', 'fan3_direction', 'fanr3_fault', 'fanr3_speed_rpm'], 'fan4': ['fan4_duty_cycle_percentage','fan4_fault', 'fan4_speed_rpm', 'fan4_direction', 'fanr4_fault', 'fanr4_speed_rpm'], 'fan5': ['fan_duty_cycle_percentage','fan5_fault', 'fan5_speed_rpm', 'fan5_direction', 'fanr5_fault', 'fanr5_speed_rpm'], } hwmon_prefix ={'led': led_prefix, 'fan1': fan_prefix, 'fan2': fan_prefix, 'fan3': fan_prefix, 'fan4': fan_prefix, 'fan5': fan_prefix, } i2c_prefix = '/sys/bus/i2c/devices/' i2c_bus = {'thermal': ['10-0048','10-0049', '10-004a'] , 'psu': ['17-0050','18-0053'], 'sfp': ['-0050']} i2c_nodes = { 'thermal': ['hwmon/hwmon*/temp1_input'] , 'psu': ['psu_present ', 'psu_power_good'] , 'sfp': ['sfp_is_present ', 'sfp_tx_disable']} sfp_map = [29, 30, 31, 32, 34, 33, 36, 35, 25, 26, 27, 28, 37, 38, 39, 40, 41, 42, 43, 44, 53, 54, 55, 56, 45, 46, 47, 48, 49, 50, 51, 52] mknod =[ 'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-0/new_device', 'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-1/new_device', 'echo as7716_32x_fan 0x66 > /sys/bus/i2c/devices/i2c-9/new_device', 'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-10/new_device', 'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-10/new_device', 'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-10/new_device', 'echo as7716_32x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-11/new_device', 'echo accton_i2c_cpld 0x62 > /sys/bus/i2c/devices/i2c-12/new_device', 'echo accton_i2c_cpld 0x64 > /sys/bus/i2c/devices/i2c-13/new_device', 'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device', 'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-2/new_device', 'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-2/new_device', 'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-2/new_device', 'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-2/new_device', # PSU-1 'echo as7716_32x_psu1 0x53 > /sys/bus/i2c/devices/i2c-18/new_device', 'echo ym2651 0x5b > /sys/bus/i2c/devices/i2c-18/new_device', # PSU-2 'echo as7716_32x_psu2 0x50> /sys/bus/i2c/devices/i2c-17/new_device', 'echo ym2651 0x58 > /sys/bus/i2c/devices/i2c-17/new_device', #EERPOM 'echo 24c02 0x56 > /sys/bus/i2c/devices/i2c-1/new_device', ] mknod2 =[ 'echo as7716_32x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-1/new_device', 'echo accton_i2c_cpld 0x61 > /sys/bus/i2c/devices/i2c-1/new_device', 'echo accton_i2c_cpld 0x62 > /sys/bus/i2c/devices/i2c-1/new_device', 'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-0/new_device', # PSU-1 'echo as7716_32x_psu1 0x38 > /sys/bus/i2c/devices/i2c-57/new_device', 'echo cpr_4011_4mxx 0x3c > /sys/bus/i2c/devices/i2c-57/new_device', 'echo as7716_32x_psu1 0x50 > /sys/bus/i2c/devices/i2c-57/new_device', 'echo ym2401 0x58 > /sys/bus/i2c/devices/i2c-57/new_device', # PSU-2 'echo as7716_32x_psu2 0x3b > /sys/bus/i2c/devices/i2c-58/new_device', 'echo cpr_4011_4mxx 0x3f > /sys/bus/i2c/devices/i2c-58/new_device', 'echo as7716_32x_psu2 0x53 > /sys/bus/i2c/devices/i2c-58/new_device', 'echo ym2401 0x5b > /sys/bus/i2c/devices/i2c-58/new_device', 'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-61/new_device', 'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-62/new_device', 'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-63/new_device', #EERPOM 'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device', ] 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 == '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-32 {0|1}\" to set sfp# tx_disable") sys.exit(0) def dis_i2c_ir3570a(addr): cmd = ["i2cset", "-y", "0", "0x"+"%x"%addr, "0xE5", "0x01"] status, output = getstatusoutput_noshell(cmd) cmd = ["i2cset", "-y", "0", "0x"+"%x"%addr, "0x12", "0x02"] status, output = getstatusoutput_noshell(cmd) return status def ir3570_check(): cmd = ["i2cdump", "-y", "0", "0x42", "s", "0x9a"] try: status, output = getstatusoutput_noshell(cmd) lines = output.split('\n') hn = re.findall(r'\w+', lines[-1]) version = int(hn[1], 16) if version == 0x24: #only for ir3570a ret = dis_i2c_ir3570a(4) else: ret = 0 except Exception as e: print("Error on ir3570_check() e:" + str(e)) return -1 return ret def show_eeprom_help(): cmd = sys.argv[0].split("/")[-1]+ " " + args[0] print(" use \""+ cmd + " 1-32 \" to dump sfp# eeprom") sys.exit(0) def my_log(txt): if DEBUG == True: print("[ACCTON DBG]: "+txt) return def log_os_system(cmd, show): logging.info('Run :'+cmd) status = 1 output = "" status, output = subprocess.getstatusoutput(cmd) my_log (cmd +"with result:" + str(status)) my_log ("cmd:" + cmd) my_log (" output:"+output) if status: logging.info('Failed :'+cmd) if show: print(('Failed :'+cmd)) return status, output def driver_inserted(): ret, lsmod = log_os_system("ls /sys/module/*accton*", 0) logging.info('mods:'+lsmod) if ret : return False else : return True #'modprobe cpr_4011_4mxx', kos = [ 'depmod -ae', 'modprobe i2c_dev', 'modprobe i2c_mux_pca954x force_deselect_on_exit=1', 'modprobe accton_i2c_cpld', 'modprobe cpr_4011_4mxx', 'modprobe ym2651y', 'modprobe accton_as7716_32x_cpld1', 'modprobe accton_as7716_32x_fan', 'modprobe accton_as7716_32x_leds', 'modprobe accton_as7716_32x_psu'] def driver_install(): global FORCE for i in range(0,len(kos)): status, output = log_os_system(kos[i], 1) if status: if FORCE == 0: return status return 0 def driver_uninstall(): global FORCE for i in range(0,len(kos)): #remove parameter if any rm = kos[-(i+1)] lst = rm.split(" ") if len(lst) > 2: del(lst[2:]) rm = " ".join(lst) #Change to removing commands rm = rm.replace("modprobe", "modprobe -rq") rm = rm.replace("insmod", "rmmod") status, output = log_os_system(rm, 1) if status: if FORCE == 0: return status return 0 def i2c_order_check(): # i2c bus 0 and 1 might be installed in different order. # Here check if 0x76 is exist @ i2c-0 tmp = "echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device" status, output = log_os_system(tmp, 0) if not device_exist(): order = 1 else: order = 0 tmp = "echo 0x70 > /sys/bus/i2c/devices/i2c-1/delete_device" status, output = log_os_system(tmp, 0) return order def device_install(): global FORCE for i in range(0,len(mknod)): #for pca932x need times to built new i2c buses if mknod[i].find('pca954') != -1: time.sleep(2) status, output = log_os_system(mknod[i], 1) if status: print(output) if FORCE == 0: return status for i in range(0,len(sfp_map)): 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 status, output =log_os_system("echo port"+str(i)+" > /sys/bus/i2c/devices/"+str(sfp_map[i])+"-0050/port_name", 1) if status: print(output) if FORCE == 0: return status return def device_uninstall(): global FORCE status, output =log_os_system("ls /sys/bus/i2c/devices/0-0070", 0) if status==0: I2C_ORDER=1 else: I2C_ORDER=0 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 if I2C_ORDER==0: nodelist = mknod else: nodelist = mknod2 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_inserted() == False: return False if not device_exist(): print("not device_exist()") return False return True def do_install(): if driver_inserted() == False: status = driver_install() if status: if FORCE == 0: return status else: print(PROJECT_NAME.upper()+" drivers detected....") ir3570_check() if not device_exist(): status = device_install() if status: if FORCE == 0: return status else: print(PROJECT_NAME.upper()+" devices detected....") return def do_uninstall(): if not device_exist(): print(PROJECT_NAME.upper() +" has no device installed....") else: print("Removing device....") status = device_uninstall() if status: if FORCE == 0: return status if driver_inserted()== False : print(PROJECT_NAME.upper() +" has no driver installed....") else: print("Removing installed driver....") status = driver_uninstall() if status: if FORCE == 0: return status return 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]): node = key+str(k+1) path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] 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()==False: print("System's 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 len(log): hex_cmd = 'hexdump' elif len(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()==False: print("System's not ready.") print("Please install first!") return if len(ALL_DEVICE)==0: 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 = log_os_system("echo "+args[1]+" >"+k, 1) if ret: return ret 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['fan1'] ['fan11'][0] node = node.replace(node.split("/")[-1], 'fan1_duty_cycle_percentage') ret, log = log_os_system("cat "+ node, 1) if ret==0: print(("Previous fan duty: " + log.strip() +"%")) ret, log = log_os_system("echo "+args[1]+" >"+node, 1) if ret==0: print(("Current fan duty: " + args[1] +"%")) return ret elif args[0]=='sfp': if int(args[1])> DEVICE_NO[args[0]] 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(0,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 = log_os_system("echo "+args[2]+" >"+ j, 1) if ret: return ret return #get digits inside a string. #Ex: 31 for "sfp31" def get_value(input): digit = re.findall('\d+', input) return int(digit[0]) def device_traversal(): if system_ready()==False: print("System's not ready.") print("Please install first!") return if len(ALL_DEVICE)==0: 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 = log_os_system("ls "+i2c_prefix+"*0077", 0) ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) return not(ret1 or ret2) if __name__ == "__main__": main()