[devices]: Add support fpga drv and pimutility for minipack platform (#3053)
This commit is contained in:
parent
e19e661080
commit
ff6437eaaa
59
device/accton/x86_64-accton_minipack-r0/plugins/led_control.py
Executable file
59
device/accton/x86_64-accton_minipack-r0/plugins/led_control.py
Executable file
@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# led_control.py
|
||||
#
|
||||
# Platform-specific LED control functionality for SONiC
|
||||
#
|
||||
|
||||
try:
|
||||
from sonic_led.led_control_base import LedControlBase
|
||||
import swsssdk
|
||||
import threading
|
||||
import os
|
||||
import logging
|
||||
import struct
|
||||
import time
|
||||
import syslog
|
||||
from socket import *
|
||||
from select import *
|
||||
from minipack.pimutil import PimUtil
|
||||
except ImportError, e:
|
||||
raise ImportError(str(e) + " - required module not found")
|
||||
|
||||
|
||||
class LedControl(LedControlBase):
|
||||
"""Platform specific LED control class"""
|
||||
SONIC_PORT_NAME_PREFIX = "Ethernet"
|
||||
|
||||
|
||||
def __init__(self):
|
||||
pim=PimUtil()
|
||||
pim.init_pim_fpga()
|
||||
|
||||
def _port_name_to_index(self, port_name):
|
||||
# Strip "Ethernet" off port name
|
||||
if not port_name.startswith(self.SONIC_PORT_NAME_PREFIX):
|
||||
return -1
|
||||
|
||||
port_idx = int(port_name[len(self.SONIC_PORT_NAME_PREFIX):])
|
||||
return port_idx
|
||||
|
||||
def _port_state_to_mode(self, port_idx, state):
|
||||
if state == "up":
|
||||
return 1, 4 #port linkup, led is green
|
||||
else:
|
||||
return 0, 0 #port linkdown, led is off
|
||||
|
||||
def port_link_state_change(self, portname, state):
|
||||
pim=PimUtil()
|
||||
port_idx = self._port_name_to_index(portname)
|
||||
new_control, led_mode = self._port_state_to_mode(port_idx, state)
|
||||
color, control=pim.get_port_led(port_idx)
|
||||
|
||||
if color==led_mode:
|
||||
if control==new_control:
|
||||
return
|
||||
|
||||
pim.set_port_led(port_idx, led_mode, new_control)#port linkup, led is green
|
||||
#port linkdown, led is off
|
||||
|
104
device/accton/x86_64-accton_minipack-r0/plugins/sfputil.py
Normal file → Executable file
104
device/accton/x86_64-accton_minipack-r0/plugins/sfputil.py
Normal file → Executable file
@ -6,6 +6,9 @@
|
||||
try:
|
||||
import time
|
||||
from sonic_sfp.sfputilbase import SfpUtilBase
|
||||
import os
|
||||
import sys, getopt
|
||||
from minipack.pimutil import PimUtil
|
||||
except ImportError as e:
|
||||
raise ImportError("%s - required module not found" % str(e))
|
||||
|
||||
@ -16,7 +19,7 @@ class SfpUtil(SfpUtilBase):
|
||||
PORT_START = 0
|
||||
PORT_END = 128
|
||||
|
||||
BASE_OOM_PATH = "/sys/bus/i2c/devices/{0}-0050/"
|
||||
LOCAL_OOM_PATH = "/usr/local/bin/minipack_qsfp/port%d_eeprom"
|
||||
|
||||
_port_to_is_present = {}
|
||||
_port_to_lp_mode = {}
|
||||
@ -53,42 +56,91 @@ class SfpUtil(SfpUtilBase):
|
||||
|
||||
|
||||
def __init__(self):
|
||||
eeprom_path = self.BASE_OOM_PATH + "eeprom"
|
||||
|
||||
for x in range(0, self.port_end+1):
|
||||
bus = self.sfp_map(x)
|
||||
self.port_to_eeprom_mapping[x] = eeprom_path.format(
|
||||
bus)
|
||||
for x in range(0, self.port_end):
|
||||
self.port_to_eeprom_mapping[x] = self.LOCAL_OOM_PATH %x
|
||||
|
||||
SfpUtilBase.__init__(self)
|
||||
pim=PimUtil()
|
||||
pim.init_pim_fpga()
|
||||
|
||||
def __del__(self):
|
||||
self.value=0
|
||||
|
||||
def get_presence(self, port_num):
|
||||
# Check for invalid port_num
|
||||
if port_num < self.port_start or port_num > self.port_end:
|
||||
return False
|
||||
|
||||
eeprom_path = self.port_to_eeprom_mapping[port_num]
|
||||
with open(eeprom_path) as f:
|
||||
try:
|
||||
content = f.read(1)
|
||||
except IOError as e:
|
||||
#Not print any error, for if any, treat as Not present.
|
||||
return False
|
||||
return True
|
||||
|
||||
pim=PimUtil()
|
||||
status=pim.get_qsfp_presence(port_num)
|
||||
return status
|
||||
|
||||
def get_low_power_mode(self, port_num):
|
||||
raise NotImplementedError
|
||||
if port_num < self.port_start or port_num > self.port_end:
|
||||
return False
|
||||
|
||||
pim=PimUtil()
|
||||
return pim.get_low_power_mode(port_num)
|
||||
|
||||
def set_low_power_mode(self, port_num, lpmode):
|
||||
raise NotImplementedError
|
||||
if port_num < self.port_start or port_num > self.port_end:
|
||||
return False
|
||||
pim=PimUtil()
|
||||
pim.set_low_power_mode(port_num, lpmode)
|
||||
return True
|
||||
|
||||
def reset(self, port_num):
|
||||
raise NotImplementedError
|
||||
if port_num < self.port_start or port_num > self.port_end:
|
||||
return False
|
||||
pim=PimUtil()
|
||||
pim.reset(port_num)
|
||||
return True
|
||||
|
||||
def get_transceiver_change_event(self, timeout=0):
|
||||
pim=PimUtil()
|
||||
start_time = time.time()
|
||||
port_dict = {}
|
||||
forever = False
|
||||
|
||||
def get_transceiver_change_event(self):
|
||||
"""
|
||||
TODO: This function need to be implemented
|
||||
when decide to support monitoring SFP(Xcvrd)
|
||||
on this platform.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
if timeout == 0:
|
||||
forever = True
|
||||
elif timeout > 0:
|
||||
timeout = timeout / float(1000) # Convert to secs
|
||||
else:
|
||||
print "get_transceiver_change_event:Invalid timeout value", timeout
|
||||
return False, {}
|
||||
|
||||
end_time = start_time + timeout
|
||||
if start_time > end_time:
|
||||
print 'get_transceiver_change_event:' \
|
||||
'time wrap / invalid timeout value', timeout
|
||||
|
||||
return False, {} # Time wrap or possibly incorrect timeout
|
||||
|
||||
while timeout >= 0:
|
||||
change_status=0
|
||||
port_dict = pim.get_qsfp_interrupt()
|
||||
present=0
|
||||
for key, value in port_dict.iteritems():
|
||||
if value==1:
|
||||
present=self.get_presence(key)
|
||||
change_status=1
|
||||
if present:
|
||||
port_dict[key]='1'
|
||||
else:
|
||||
port_dict[key]='0'
|
||||
|
||||
if change_status:
|
||||
return True, port_dict
|
||||
if forever:
|
||||
time.sleep(1)
|
||||
else:
|
||||
timeout = end_time - time.time()
|
||||
if timeout >= 1:
|
||||
time.sleep(1) # We poll at 1 second granularity
|
||||
else:
|
||||
if timeout > 0:
|
||||
time.sleep(timeout)
|
||||
return True, {}
|
||||
print "get_evt_change_event: Should not reach here."
|
||||
return False, {}
|
||||
|
578
platform/broadcom/sonic-platform-modules-accton/minipack/classes/pimutil.py
Executable file
578
platform/broadcom/sonic-platform-modules-accton/minipack/classes/pimutil.py
Executable file
@ -0,0 +1,578 @@
|
||||
# Copyright (c) 2019 Edgecore Networks Corporation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
|
||||
# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS
|
||||
# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||
#
|
||||
# See the Apache Version 2.0 License for specific language governing
|
||||
# permissions and limitations under the License.
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# HISTORY:
|
||||
# mm/dd/yyyy (A.D.)
|
||||
# 5/29/2019: Jostar create for minipack
|
||||
# -----------------------------------------------------------
|
||||
try:
|
||||
import os
|
||||
import sys, getopt
|
||||
import subprocess
|
||||
import click
|
||||
import imp
|
||||
import logging
|
||||
import logging.config
|
||||
import logging.handlers
|
||||
import types
|
||||
import time # this is only being used as part of the example
|
||||
import traceback
|
||||
from tabulate import tabulate
|
||||
import fbfpgaio
|
||||
import re
|
||||
import time
|
||||
from select import select
|
||||
#from ctypes import fbfpgaio
|
||||
|
||||
except ImportError as e:
|
||||
raise ImportError('%s - required module not found' % str(e))
|
||||
|
||||
|
||||
# pimutil.py
|
||||
#
|
||||
# Platform-specific PIM interface for SONiC
|
||||
#
|
||||
|
||||
iob = {
|
||||
"revision": 0x0,
|
||||
"scratchpad": 0x4,
|
||||
"interrupt_status": 0x2C,
|
||||
"pim_status": 0x40,
|
||||
"pim_present_intr_mask": 0x44,
|
||||
}
|
||||
|
||||
dom_base = [
|
||||
0xFFFFFFFF, # Padding
|
||||
0x40000,
|
||||
0x48000,
|
||||
0x50000,
|
||||
0x58000,
|
||||
0x60000,
|
||||
0x68000,
|
||||
0x70000,
|
||||
0x78000,
|
||||
]
|
||||
|
||||
|
||||
dom = {
|
||||
"revision": 0x0,
|
||||
"system_led": 0xC,
|
||||
"intr_status": 0x2C,
|
||||
"qsfp_present": 0x48,
|
||||
"qsfp_present_intr": 0x50,
|
||||
"qsfp_present_intr_mask": 0x58,
|
||||
"qsfp_intr": 0x60,
|
||||
"qsfp_intr_mask": 0x68,
|
||||
"qsfp_reset": 0x70,
|
||||
"qsfp_lp_mode": 0x78,
|
||||
"device_power_bad_status": 0x90,
|
||||
"port_led_color_profile": {
|
||||
0: 0x300,
|
||||
1: 0x300,
|
||||
2: 0x304,
|
||||
3: 0x304,
|
||||
4: 0x308,
|
||||
5: 0x308,
|
||||
6: 0x30C,
|
||||
7: 0x30C,
|
||||
},
|
||||
"port_led_control": {
|
||||
1: 0x310,
|
||||
2: 0x314,
|
||||
3: 0x318,
|
||||
4: 0x31C,
|
||||
5: 0x320,
|
||||
6: 0x324,
|
||||
7: 0x328,
|
||||
8: 0x32C,
|
||||
9: 0x330,
|
||||
10: 0x334,
|
||||
11: 0x338,
|
||||
12: 0x33C,
|
||||
13: 0x340,
|
||||
14: 0x344,
|
||||
15: 0x348,
|
||||
16: 0x34C,
|
||||
},
|
||||
"dom_control_config": 0x410,
|
||||
"dom_global_status": 0x414,
|
||||
"dom_data": 0x4000,
|
||||
|
||||
|
||||
"mdio": {
|
||||
"config": 0x0200,
|
||||
"command": 0x0204,
|
||||
"write": 0x0208,
|
||||
"read": 0x020C,
|
||||
"status": 0x0210,
|
||||
"intr_mask": 0x0214,
|
||||
"source_sel": 0x0218,
|
||||
}, # mdio
|
||||
}
|
||||
|
||||
mdio_read_cmd = 0x1
|
||||
mdio_write_cmd = 0x0
|
||||
mdio_device_type = 0x1F
|
||||
|
||||
|
||||
#fbfpgaio=cdll.LoadLibrary('./fbfpgaio.so')
|
||||
|
||||
def init_resources():
|
||||
fbfpgaio.hw_init()
|
||||
return
|
||||
|
||||
def release_resources():
|
||||
fbfpgaio.hw_release()
|
||||
return
|
||||
|
||||
def fpga_io(offset, data=None):
|
||||
if data is None:
|
||||
return fbfpgaio.hw_io(offset)
|
||||
else:
|
||||
fbfpgaio.hw_io(offset, data)
|
||||
return
|
||||
|
||||
def pim_io(pim, offset, data=None):
|
||||
global dom_base
|
||||
target_offset = dom_base[pim]+offset
|
||||
if data is None:
|
||||
retval = fpga_io(target_offset)
|
||||
#print ("0x%04X" % retval) # idebug
|
||||
return retval
|
||||
else:
|
||||
retval = fpga_io(target_offset, data)
|
||||
return retval
|
||||
|
||||
|
||||
def show_pim_present():
|
||||
pim_status = fpga_io(iob["pim_status"])
|
||||
|
||||
header = "PIM # "
|
||||
status_str = " "
|
||||
for shift in range(0,8):
|
||||
status = pim_status & (0x10000 << shift) #[23:16] from pim_0 to pim_7
|
||||
header += " %d " % (shift+1)
|
||||
if status:
|
||||
status_str += (" | ")
|
||||
else:
|
||||
status_str += (" X ")
|
||||
print(header)
|
||||
print(status_str)
|
||||
|
||||
def show_qsfp_present_status(pim_num):
|
||||
status = fpga_io(dom_base[pim_num]+dom["qsfp_present"])
|
||||
interrupt = fpga_io(dom_base[pim_num]+dom["qsfp_present_intr"])
|
||||
mask = fpga_io(dom_base[pim_num]+dom["qsfp_present_intr_mask"])
|
||||
|
||||
print
|
||||
print(" (0x48) (0x50) (0x58)")
|
||||
print(" 0x%08X 0x%08X 0x%08X" %(status, interrupt, mask))
|
||||
print(" Status Interrupt Mask")
|
||||
for row in range(8):
|
||||
output_str = str()
|
||||
status_left = bool(status & (0x1 << row*2))
|
||||
status_right = bool(status & (0x2 << row*2))
|
||||
interrupt_left = bool(interrupt & (0x1 << row*2))
|
||||
interrupt_right = bool(interrupt & (0x2 << row*2))
|
||||
mask_left = bool(mask & (0x1 << row*2))
|
||||
mask_right = bool(mask & (0x2 << row*2))
|
||||
print("%2d: %d %d %d %d %d %d" % \
|
||||
(row*2+1, status_left, status_right, \
|
||||
interrupt_left, interrupt_right, \
|
||||
mask_left, mask_right))
|
||||
print
|
||||
|
||||
|
||||
|
||||
#pim_index start from 0 to 7
|
||||
#port_index start from 0 to 127. Each 16-port is to one pim card.
|
||||
class PimUtil(object):
|
||||
|
||||
PORT_START = 0
|
||||
PORT_END = 127
|
||||
|
||||
def __init__(self):
|
||||
self.value=1
|
||||
|
||||
def __del__(self):
|
||||
self.value=0
|
||||
|
||||
def init_pim_fpga(self):
|
||||
init_resources()
|
||||
|
||||
def release_pim_fpga(self):
|
||||
release_resources()
|
||||
|
||||
def get_pim_by_port(self, port_num):
|
||||
if port_num < self.PORT_START or port_num > self.PORT_END:
|
||||
return False
|
||||
pim_num=port_num/16
|
||||
return True, pim_num+1
|
||||
|
||||
def get_onepimport_by_port(self, port_num):
|
||||
if port_num < self.PORT_START or port_num > self.PORT_END:
|
||||
return False
|
||||
if port_num < 16:
|
||||
return True, port_num
|
||||
else:
|
||||
return True, port_num%16
|
||||
|
||||
def get_pim_presence(self, pim_num):
|
||||
if pim_num <0 or pim_num > 7:
|
||||
return 0
|
||||
pim_status = fpga_io(iob["pim_status"])
|
||||
status = pim_status & (0x10000 << pim_num)
|
||||
if status:
|
||||
return 1 #present
|
||||
else:
|
||||
return 0 #not present
|
||||
|
||||
#return code=0:100G. return code=1:400G
|
||||
def get_pim_board_id(self, pim_num):
|
||||
if pim_num <0 or pim_num > 7:
|
||||
return False
|
||||
board_id = fpga_io(dom_base[pim_num+1]+dom["revision"])
|
||||
board_id = board_id & 0x1
|
||||
if board_id==0x0:
|
||||
return 0
|
||||
else:
|
||||
return 1
|
||||
|
||||
|
||||
def get_pim_status(self, pim_num):
|
||||
if pim_num <0 or pim_num > 7:
|
||||
return 0xFF
|
||||
power_status =0
|
||||
#device_power_bad_status
|
||||
status=fpga_io(dom_base[pim_num+1]+dom["device_power_bad_status"])
|
||||
|
||||
for x in range(0, 5):
|
||||
if status & ( (0xf) << (4*x) ) :
|
||||
power_status = power_status | (0x1 << x)
|
||||
|
||||
if ( status & 0x1000000):
|
||||
power_status=power_status | (0x1 << 5)
|
||||
if ( status & 0x2000000):
|
||||
power_status=power_status | (0x1 << 6)
|
||||
if ( status & 0x8000000):
|
||||
power_status=power_status | (0x1 << 7)
|
||||
if ( status & 0x10000000):
|
||||
power_status=power_status | (0x1 << 8)
|
||||
if ( status & 0x40000000):
|
||||
power_status=power_status | (0x1 << 9)
|
||||
if ( status & 0x80000000):
|
||||
power_status=power_status | (0x1 << 10)
|
||||
|
||||
return power_status
|
||||
#path=0:MDIO path is set on TH3. path=1:MDIO path is set on FPGA.
|
||||
def set_pim_mdio_source_sel(self, pim_num, path):
|
||||
if pim_num <0 or pim_num > 7:
|
||||
return False
|
||||
status= pim_io(pim_num+1, dom["mdio"]["source_sel"])
|
||||
|
||||
if path==1:
|
||||
status = status | 0x2
|
||||
else:
|
||||
status = status & 0xfffffffd
|
||||
|
||||
pim_io(pim_num+1, dom["mdio"]["source_sel"], status)
|
||||
return True
|
||||
#retrun code=0, path is TH3. retrun code=1, path is FPGA
|
||||
def get_pim_mdio_source_sel(sefl, pim_num):
|
||||
if pim_num <0 or pim_num > 7:
|
||||
return False
|
||||
path= pim_io(pim_num+1, dom["mdio"]["source_sel"])
|
||||
path = path & 0x2
|
||||
if path:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
#This api will set mdio path to MAC side.(At default, mdio path is set to FPGA side).
|
||||
def pim_init(self, pim_num):
|
||||
if pim_num <0 or pim_num > 7:
|
||||
return False
|
||||
status=self.set_pim_mdio_source_sel(pim_num, 0)
|
||||
#put init phy cmd here
|
||||
|
||||
|
||||
#return code="pim_dict[pim_num]='1' ":insert evt. return code="pim_dict[pim_num]='0' ":remove evt
|
||||
def get_pim_change_event(self, timeout=0):
|
||||
start_time = time.time()
|
||||
pim_dict = {}
|
||||
forever = False
|
||||
|
||||
if timeout == 0:
|
||||
forever = True
|
||||
elif timeout > 0:
|
||||
timeout = timeout / float(1000) # Convert to secs
|
||||
else:
|
||||
print "get_transceiver_change_event:Invalid timeout value", timeout
|
||||
return False, {}
|
||||
|
||||
end_time = start_time + timeout
|
||||
if start_time > end_time:
|
||||
print 'get_transceiver_change_event:' \
|
||||
'time wrap / invalid timeout value', timeout
|
||||
|
||||
return False, {} # Time wrap or possibly incorrect timeout
|
||||
|
||||
pim_mask_status = fpga_io(iob["pim_present_intr_mask"], 0xffff00000)
|
||||
|
||||
while timeout >= 0:
|
||||
new_pim_status=0
|
||||
pim_status = fpga_io(iob["pim_status"])
|
||||
present_status= pim_status & 0xff0000
|
||||
change_status=pim_status & 0xff
|
||||
interrupt_status = fpga_io(iob["interrupt_status"])
|
||||
|
||||
for pim_num in range(0,8):
|
||||
if change_status & (0x1 << pim_num) :
|
||||
status = present_status & (0x10000 << pim_num)
|
||||
new_pim_status = new_pim_status | (0x1 << pim_num) #prepare to W1C to clear
|
||||
if status:
|
||||
pim_dict[pim_num]='1'
|
||||
else:
|
||||
pim_dict[pim_num]='0'
|
||||
|
||||
if change_status:
|
||||
new_pim_status = pim_status | new_pim_status #Write one to clear interrupt bit
|
||||
fpga_io(iob["pim_status"], new_pim_status)
|
||||
return True, pim_dict
|
||||
if forever:
|
||||
time.sleep(1)
|
||||
else:
|
||||
timeout = end_time - time.time()
|
||||
if timeout >= 1:
|
||||
time.sleep(1) # We poll at 1 second granularity
|
||||
else:
|
||||
if timeout > 0:
|
||||
time.sleep(timeout)
|
||||
return True, {}
|
||||
print "get_evt_change_event: Should not reach here."
|
||||
return False, {}
|
||||
|
||||
|
||||
def get_pim_max_number(self):
|
||||
return 8
|
||||
|
||||
#pim_num start from 0 to 7
|
||||
#color:0=amber, 1=blue
|
||||
#contrl:off(0),on(1), flash(2)
|
||||
def set_pim_led(self, pim_num, color, control):
|
||||
if pim_num <0 or pim_num > 7:
|
||||
return False
|
||||
|
||||
led_val=fpga_io(dom_base[pim_num+1]+dom["system_led"])
|
||||
|
||||
if color==1:
|
||||
led_val = led_val | (0x8000 | 0x4000) #blue
|
||||
elif color==0:
|
||||
led_val = (led_val & ( ~ 0x8000)) | 0x4000 #amber
|
||||
else:
|
||||
print "Set RGB control to Green1"
|
||||
led_val = led_val & (~ 0x4000)
|
||||
led_val = led_val & (~ 0xfff)
|
||||
led_val = led_val | 0x0f0 #B.G.R Birghtness, set to Green
|
||||
|
||||
if control==0:
|
||||
led_val = led_val & ( ~ 0x3000) #Off
|
||||
elif control==1:
|
||||
led_val = led_val & ( ~ 0x3000) #Off
|
||||
led_val = led_val | 0x1000 #On
|
||||
else:
|
||||
led_val = led_val | 0x3000 #Flash
|
||||
|
||||
fpga_io(dom_base[pim_num+1]+dom["system_led"], led_val)
|
||||
|
||||
def get_qsfp_presence(self, port_num):
|
||||
#xlate port to get pim_num
|
||||
status, pim_num=self.get_pim_by_port(port_num)
|
||||
|
||||
if status==0:
|
||||
return False
|
||||
else:
|
||||
present = fpga_io(dom_base[pim_num]+dom["qsfp_present"])
|
||||
status, shift = self.get_onepimport_by_port(port_num)
|
||||
if status==0:
|
||||
return False
|
||||
else:
|
||||
if bool(present & (0x1 << shift)):
|
||||
return 1 #present
|
||||
else:
|
||||
return 0 #not present
|
||||
|
||||
#return code: low_power(1) or high_power(0)
|
||||
def get_low_power_mode(self, port_num):
|
||||
status, pim_num=self.get_pim_by_port(port_num)
|
||||
|
||||
if status==0:
|
||||
return False
|
||||
else:
|
||||
lp_mode = fpga_io(dom_base[pim_num]+dom["qsfp_lp_mode"])
|
||||
|
||||
status, shift=self.get_onepimport_by_port(port_num)
|
||||
if status==0:
|
||||
return False
|
||||
else:
|
||||
if (lp_mode & (0x1 << shift)):
|
||||
return 1 #low
|
||||
else:
|
||||
return 0 #high
|
||||
|
||||
#lpmode=1 to hold QSFP in low power mode. lpmode=0 to release QSFP from low power mode.
|
||||
def set_low_power_mode(self, port_num, mode):
|
||||
status, pim_num=self.get_pim_by_port(port_num)
|
||||
if status==0:
|
||||
return False
|
||||
val = fpga_io(dom_base[pim_num]+dom["qsfp_lp_mode"])
|
||||
status, shift=self.get_onepimport_by_port(port_num)
|
||||
if status==0:
|
||||
return False
|
||||
else:
|
||||
if mode==0:
|
||||
new_val = val & (~(0x1 << shift))
|
||||
else:
|
||||
new_val=val|(0x1 << shift)
|
||||
status=fpga_io(dom_base[pim_num]+dom["qsfp_lp_mode"], new_val)
|
||||
return status
|
||||
|
||||
#port_dict[idx]=1 means get interrupt(change evt), port_dict[idx]=0 means no get interrupt
|
||||
def get_qsfp_interrupt(self):
|
||||
port_dict={}
|
||||
#show_qsfp_present_status(1)
|
||||
for pim_num in range(0, 8):
|
||||
fpga_io(dom_base[pim_num+1]+dom["qsfp_present_intr_mask"], 0xffff0000)
|
||||
fpga_io(dom_base[pim_num+1]+dom["qsfp_intr_mask"], 0xffff0000)
|
||||
for pim_num in range(0, 8):
|
||||
clear_bit=0
|
||||
qsfp_present_intr_status = fpga_io(dom_base[pim_num+1]+dom["qsfp_present_intr"])
|
||||
interrupt_status = qsfp_present_intr_status & 0xffff
|
||||
#time.sleep(2)
|
||||
if interrupt_status:
|
||||
for idx in range (0,16):
|
||||
port_idx=idx + (pim_num*16)
|
||||
if interrupt_status & (0x1<<idx):
|
||||
port_dict[port_idx]=1
|
||||
clear_bit=clear_bit | (0x1<<idx) #W1C to clear
|
||||
else:
|
||||
port_dict[port_idx]=0
|
||||
|
||||
#W1C to clear
|
||||
fpga_io(dom_base[pim_num+1]+dom["qsfp_present_intr"], qsfp_present_intr_status | clear_bit)
|
||||
|
||||
return port_dict
|
||||
|
||||
def reset(self, port_num):
|
||||
status, pim=self.get_pim_by_port(port_num)
|
||||
if status==0:
|
||||
return False
|
||||
|
||||
val=fpga_io(dom_base[pim]+dom["qsfp_reset"])
|
||||
status, shift=self.get_onepimport_by_port(port_num)
|
||||
if status==0:
|
||||
return False
|
||||
else:
|
||||
val = val & (~(0x1 << shift))
|
||||
fpga_io(dom_base[pim]+dom["qsfp_reset"], val)
|
||||
return True
|
||||
|
||||
#color:white(0), blue(1),red(2), orange(3),green(4)
|
||||
def set_port_led(self, port_num, color, control):
|
||||
status, pim_num=self.get_pim_by_port(port_num)
|
||||
if status==0:
|
||||
return False
|
||||
status, port=self.get_onepimport_by_port(port_num)
|
||||
port=port+1
|
||||
led_val=fpga_io(dom_base[pim_num] + dom["port_led_control"][port])
|
||||
if control==0:
|
||||
led_val = led_val & (~ 0x3) #Off
|
||||
elif control==1:
|
||||
led_val = led_val & (~ 0x3) #Off
|
||||
led_val = led_val | 0x1 #On
|
||||
else:
|
||||
led_val = led_val | 0x3 #Flash
|
||||
|
||||
led_val=led_val & (~ 0x1C)
|
||||
if color==0:
|
||||
led_val=led_val & (~ 0x1C) #white
|
||||
elif color==1:
|
||||
led_val=led_val | 0x8 #blue
|
||||
elif color==2:
|
||||
led_val=led_val | 0x10 #red
|
||||
elif color==3:
|
||||
led_val=led_val | 0x14 #oragne
|
||||
else:
|
||||
led_val=led_val | 0x1C #green
|
||||
|
||||
fpga_io(dom_base[pim_num] + dom["port_led_control"][port], led_val)
|
||||
|
||||
return True
|
||||
|
||||
def get_port_led(self, port_num):
|
||||
status, pim_num=self.get_pim_by_port(port_num)
|
||||
if status==0:
|
||||
return False
|
||||
status, port=self.get_onepimport_by_port(port_num)
|
||||
led_val=fpga_io(dom_base[pim_num] + dom["port_led_control"][port+1])
|
||||
control=led_val & 0x3
|
||||
if control==0x3:
|
||||
control=2
|
||||
elif control==0x1:
|
||||
control=1
|
||||
else:
|
||||
control=0
|
||||
|
||||
color = led_val & 0x1C
|
||||
if color==0:
|
||||
color=0 #white
|
||||
elif color==0xC:
|
||||
color=1 #blue
|
||||
elif color==0x14:
|
||||
color=2 #red
|
||||
elif color==0x18:
|
||||
color=3 #oragne
|
||||
elif color==0x1C:
|
||||
color=4 #green
|
||||
|
||||
print "color=%d, control=%d"%(color, control)
|
||||
return color, control
|
||||
|
||||
def main(argv):
|
||||
init_resources()
|
||||
pim=PimUtil()
|
||||
print "Test Board ID"
|
||||
for x in range(0,8):
|
||||
val=pim.get_pim_board_id(x)
|
||||
print "pim=%d"%x
|
||||
if val==0:
|
||||
print "100G board"
|
||||
else:
|
||||
print "400G board"
|
||||
|
||||
print "Test pim presence"
|
||||
for x in range(0,8):
|
||||
pres=pim.get_pim_presence(x)
|
||||
print "pim=%d, presence=%d"%(x, pres)
|
||||
|
||||
print "Test pim status"
|
||||
for x in range(0,8):
|
||||
power_status=pim.get_pim_status(x)
|
||||
print "pim=%d power_status=0x%x"%(x, power_status)
|
||||
|
||||
release_resources()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv[1:])
|
126
platform/broadcom/sonic-platform-modules-accton/minipack/lib/fbfpgaiomodule.c
Executable file
126
platform/broadcom/sonic-platform-modules-accton/minipack/lib/fbfpgaiomodule.c
Executable file
@ -0,0 +1,126 @@
|
||||
# Copyright (c) 2019 Edgecore Networks Corporation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
|
||||
# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS
|
||||
# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||
#
|
||||
# See the Apache Version 2.0 License for specific language governing
|
||||
# permissions and limitations under the License.
|
||||
|
||||
#include <Python.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
//#define IDEBUG(...) printf(__VA_ARGS__)
|
||||
#define IDEBUG(...)
|
||||
|
||||
#define FPGA_RESOURCE_NODE "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0/resource0"
|
||||
#define FPGA_RESOURCE_LENGTH 0x80000
|
||||
|
||||
|
||||
static int hw_handle = -1;
|
||||
static void *io_base = NULL;
|
||||
|
||||
static PyObject *fbfpgaio_hw_init(PyObject *self)
|
||||
{
|
||||
const char fpga_resource_node[] = FPGA_RESOURCE_NODE;
|
||||
|
||||
/* Open hardware resource node */
|
||||
hw_handle = open(fpga_resource_node, O_RDWR|O_SYNC);
|
||||
if (hw_handle == -1) {
|
||||
IDEBUG("[ERROR] %s: open hw resource node\n", __func__);
|
||||
return Py_False;
|
||||
}
|
||||
|
||||
IDEBUG("[PASS] %s: open hw resource node\n", __func__);
|
||||
|
||||
/* Mapping hardware resource */
|
||||
io_base = mmap(NULL, FPGA_RESOURCE_LENGTH, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_NORESERVE, hw_handle, 0);
|
||||
if (io_base == MAP_FAILED) {
|
||||
IDEBUG("[ERROR] %s: mapping resource node\n", __func__);
|
||||
perror("map_failed");
|
||||
fprintf(stderr,"%d %s\\n",errno,strerror(errno));
|
||||
return Py_False;
|
||||
}
|
||||
|
||||
IDEBUG("[PASS] %s: mapping resource node\n", __func__);
|
||||
|
||||
return Py_True;
|
||||
}
|
||||
|
||||
static PyObject *fbfpgaio_hw_release(PyObject *self)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if ((io_base != NULL) && (io_base != MAP_FAILED)) {
|
||||
retval = munmap(io_base, FPGA_RESOURCE_LENGTH);
|
||||
if (retval == 0) {
|
||||
IDEBUG("[PASS] %s: Unmapping hardware resources\n", __func__);
|
||||
close(hw_handle);
|
||||
return Py_True;
|
||||
}
|
||||
}
|
||||
|
||||
IDEBUG("[ERROR] %s: unmapping resource node\n", __func__);
|
||||
return Py_False;
|
||||
}
|
||||
|
||||
static PyObject *fbfpgaio_hw_io(PyObject *self, PyObject *args)
|
||||
{
|
||||
void *offset = NULL;
|
||||
/* We are not able to diffrentiate the input data between an unsigned value or a
|
||||
'None' object. We assume that the input data (if any) will be an unsigned integer.
|
||||
The default value of 'data' is larger than the max. number of unsigned integer.
|
||||
This value signify that the caller of this function does not input a data argument. */
|
||||
unsigned long input_data = 0x1FFFFFFFF;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "I|k", &offset, &input_data)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (input_data == 0x1FFFFFFFF) {
|
||||
// Read operation
|
||||
IDEBUG("Read operation\n");
|
||||
unsigned int *address = (unsigned int *) ((unsigned long) io_base + (unsigned long) offset);
|
||||
return Py_BuildValue("k", *address);
|
||||
} else {
|
||||
// Write operation
|
||||
IDEBUG("Write operation\n");
|
||||
unsigned int *address = (unsigned int *) ((unsigned long) io_base + (unsigned long) offset);
|
||||
unsigned int data = (unsigned int) (input_data & 0xFFFFFFFF);
|
||||
*address = data;
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
}
|
||||
|
||||
static PyMethodDef FbfpgaMethods[] = {
|
||||
{ "hw_init", (PyCFunction) fbfpgaio_hw_init, METH_NOARGS, "Initialize resources for accessing FPGA" },
|
||||
{ "hw_release", (PyCFunction) fbfpgaio_hw_release, METH_NOARGS, "Release resources for accessing FPGA" },
|
||||
{ "hw_io", fbfpgaio_hw_io, METH_VARARGS, "Access FPGA" },
|
||||
{ NULL, NULL, 0, NULL },
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
initfbfpgaio(void)
|
||||
{
|
||||
char docstr[] = "\
|
||||
1. hw_init():\n\
|
||||
return value: True/False\n\
|
||||
2. hw_release():\n\
|
||||
return value: True/False\n\
|
||||
3. hw_io(offset,[data])\n\
|
||||
return value:\n\
|
||||
In reading operation: data which is read from FPGA\n\
|
||||
In writing operation: None\n";
|
||||
|
||||
(void) Py_InitModule3("fbfpgaio", FbfpgaMethods, docstr);
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
[Unit]
|
||||
Description=Accton MiniPack Platform setup qsfp oom service
|
||||
Before=pmon.service
|
||||
After=minipack-platform-init.service
|
||||
DefaultDependencies=no
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/setup_qsfp_eeprom.py
|
||||
KillSignal=SIGKILL
|
||||
SuccessExitStatus=SIGKILL
|
||||
|
||||
# Resource Limitations
|
||||
LimitCORE=infinity
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
6
platform/broadcom/sonic-platform-modules-accton/minipack/setup.py
Normal file → Executable file
6
platform/broadcom/sonic-platform-modules-accton/minipack/setup.py
Normal file → Executable file
@ -2,9 +2,11 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
from setuptools import setup
|
||||
from setuptools import setup, Extension
|
||||
os.listdir
|
||||
|
||||
module1 = Extension("fbfpgaio", sources = ["minipack/lib/fbfpgaiomodule.c"])
|
||||
|
||||
setup(
|
||||
name='minipack',
|
||||
version='1.0',
|
||||
@ -12,5 +14,7 @@ setup(
|
||||
|
||||
packages=['minipack'],
|
||||
package_dir={'minipack': 'minipack/classes'},
|
||||
ext_modules=[module1],
|
||||
|
||||
)
|
||||
|
||||
|
@ -238,7 +238,7 @@ def device_install():
|
||||
for i in range(0,len(mknod)):
|
||||
#for pca932x need times to built new i2c buses
|
||||
if mknod[i].find('pca954') != -1:
|
||||
time.sleep(1)
|
||||
time.sleep(2)
|
||||
|
||||
status, output = log_os_system(mknod[i], 1)
|
||||
if status:
|
||||
@ -246,49 +246,14 @@ def device_install():
|
||||
if FORCE == 0:
|
||||
return status
|
||||
|
||||
# initialize multiplexer for 8 PIMs
|
||||
cmdl = "echo pca9548 0x%x > /sys/bus/i2c/devices/i2c-%d/new_device"
|
||||
for pim in range(2, 10):
|
||||
cmdm = cmdl % (0x72, pim)
|
||||
status, output =log_os_system(cmdm, 1)
|
||||
cmdm = cmdl % (0x71, pim)
|
||||
status, output =log_os_system(cmdm, 1)
|
||||
|
||||
for i in range(0, NO_QSFP):
|
||||
bus = sfp_map(i)
|
||||
status, output =log_os_system(
|
||||
"echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(bus)+"/new_device", 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
status, output =log_os_system(
|
||||
"echo port"+str(i+1)+" > /sys/bus/i2c/devices/"+str(bus)+"-0050/port_name", 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
rm_cmd="rm -rf /usr/local/bin/minipack_qsfp > /dev/null 2>&1"
|
||||
log_os_system(rm_cmd, 1)
|
||||
mk_cmd= "mkdir /usr/local/bin/minipack_qsfp"
|
||||
log_os_system(mk_cmd, 1)
|
||||
|
||||
return
|
||||
|
||||
def device_uninstall():
|
||||
for i in range(0,NO_QSFP):
|
||||
bus = sfp_map(i)
|
||||
target = "/sys/bus/i2c/devices/i2c-"+str(bus)+"/delete_device"
|
||||
status, output =log_os_system("echo 0x50 > "+ target, 1)
|
||||
if status:
|
||||
print output
|
||||
if FORCE == 0:
|
||||
return status
|
||||
|
||||
# Multiplexer for 8 PIMs
|
||||
cmdl = "echo 0x%x > /sys/bus/i2c/devices/i2c-%d/delete_device"
|
||||
for pim in range(2, 10):
|
||||
cmdm = cmdl % (0x72, pim)
|
||||
status, output =log_os_system(cmdm, 1)
|
||||
cmdm = cmdl % (0x71, pim)
|
||||
status, output =log_os_system(cmdm, 1)
|
||||
|
||||
nodelist = mknod
|
||||
for i in range(len(nodelist)):
|
||||
target = nodelist[-(i+1)]
|
||||
|
@ -0,0 +1,317 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (c) 2019 Edgecore Networks Corporation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
|
||||
# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS
|
||||
# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||
#
|
||||
# See the Apache Version 2.0 License for specific language governing
|
||||
# permissions and limitations under the License.
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# HISTORY:
|
||||
# mm/dd/yyyy (A.D.)
|
||||
# 7/22/2019: Jostar create for minipack
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
try:
|
||||
import os
|
||||
import sys, getopt
|
||||
import subprocess
|
||||
import subprocess
|
||||
import click
|
||||
import imp
|
||||
import commands
|
||||
import logging
|
||||
import logging.config
|
||||
import logging.handlers
|
||||
import types
|
||||
import time # this is only being used as part of the example
|
||||
import traceback
|
||||
from tabulate import tabulate
|
||||
from minipack.pimutil import PimUtil
|
||||
except ImportError as e:
|
||||
raise ImportError('%s - required module not found' % str(e))
|
||||
|
||||
#2:idle state. 1:insert state, 0:remove state.
|
||||
pim_state=[2,2,2,2,2,2,2,2]
|
||||
|
||||
# port_use_i2c_bus[idx], idx means port_idx. Idx start from 0 to 127
|
||||
# port_use_i2c_bus[0] means port0 use i2c-device number
|
||||
# port_use_i2c_bus[1] means port1 use i2c-device number
|
||||
#At default , port_use_i2c_bus are 0. When PIM insert, it will no be 0
|
||||
port_use_i2c_bus= [0] * 128
|
||||
|
||||
#pim_port_use_bus[idx] are for 8 channel use. At default, pim_port_use_bus[idx]=0
|
||||
#pim_port_use_bus[idx] will save pim_idx(0 to 7).
|
||||
#setup service will check when pim insert at first time.
|
||||
#It will find
|
||||
# 1. Does this pim card insert or not in the past. So it will check pim_port_use_bus[idx]
|
||||
# 2. If make sure that pim_port_use_bus[idx]==0. Assgin oom start i2c dev numer to pim_port_use_bus[idx].
|
||||
#Never set pim_port_use_bus[idx] to 0
|
||||
#So if pim next insert, it need to check whether pim_port_use_bus[idx] is 0 or not.
|
||||
#if pim_port_use_bus[idx]!=0, means this pim card has setup oom sysfs
|
||||
pim_port_use_bus=[0] * 8
|
||||
|
||||
oom_i2c_bus_table=1
|
||||
|
||||
pim_dev=PimUtil()
|
||||
|
||||
# Deafults
|
||||
VERSION = '1.0'
|
||||
FUNCTION_NAME = '/usr/local/bin/setup_qsfp_eeprom'
|
||||
DEBUG = False
|
||||
PIM_MIN=0
|
||||
PIM_MAX=8
|
||||
|
||||
def my_log(txt):
|
||||
if DEBUG == True:
|
||||
print "[ACCTON DBG]: "+txt
|
||||
return
|
||||
|
||||
def log_os_system(cmd):
|
||||
logging.info('Run :'+cmd)
|
||||
status = 1
|
||||
output = ""
|
||||
status, output = commands.getstatusoutput(cmd)
|
||||
if status:
|
||||
logging.info('Failed :'+cmd)
|
||||
return status, output
|
||||
|
||||
def qsfp_map_bus(idx):
|
||||
port = idx + 1
|
||||
base = ((port-1)/8*8) + 10
|
||||
idx = (port - 1) % 8
|
||||
idx = 7 - idx
|
||||
if (idx%2):
|
||||
idx = idx -1
|
||||
else:
|
||||
idx = idx +1
|
||||
bus = base + idx
|
||||
return bus
|
||||
|
||||
def pca9548_sysfs(i2c_bus, create):
|
||||
if create==1:
|
||||
cmdl = "echo pca9548 0x%x > /sys/bus/i2c/devices/i2c-%d/new_device"
|
||||
else:
|
||||
cmdl = "echo 0x%x > /sys/bus/i2c/devices/i2c-%d/delete_device"
|
||||
|
||||
cmdm = cmdl % (0x72, i2c_bus)
|
||||
status1, output =log_os_system(cmdm)
|
||||
cmdm = cmdl % (0x71, i2c_bus)
|
||||
status2, output =log_os_system(cmdm)
|
||||
return (status1 | status2)
|
||||
|
||||
|
||||
def qsfp_eeprom_sys(pim_idx, i2c_bus_order, create):
|
||||
# initialize multiplexer for 8 PIMs
|
||||
global port_use_i2c_bus
|
||||
start_port=pim_idx*16
|
||||
end_port = (pim_idx+1)*16
|
||||
start_bus=(i2c_bus_order-1)*16
|
||||
end_bus = i2c_bus_order*16
|
||||
k=start_port
|
||||
for i in range(start_bus, end_bus):
|
||||
bus = qsfp_map_bus(i)
|
||||
if create==1:
|
||||
status, output =log_os_system(
|
||||
"echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(bus)+"/new_device")
|
||||
if status:
|
||||
print output
|
||||
return 1
|
||||
status, output =log_os_system(
|
||||
"echo port"+str(k+1)+" > /sys/bus/i2c/devices/"+str(bus)+"-0050/port_name")
|
||||
|
||||
status, output =log_os_system(
|
||||
"ln -s -f /sys/bus/i2c/devices/"+str(bus)+"-0050/eeprom" + " /usr/local/bin/minipack_qsfp/port" + str(k) + "_eeprom")
|
||||
if status:
|
||||
print output
|
||||
return 1
|
||||
else:
|
||||
status, output =log_os_system(
|
||||
"echo 0x50 > /sys/bus/i2c/devices/i2c-"+str(bus)+"/delete_device")
|
||||
if status:
|
||||
print output
|
||||
|
||||
k=k+1
|
||||
|
||||
return 0
|
||||
|
||||
def check_pca_active( i2c_addr, bus):
|
||||
cmd = "i2cget -y -f %d 0x%x 0x0"
|
||||
cmd = cmd %(bus, i2c_addr)
|
||||
status, output = commands.getstatusoutput(cmd)
|
||||
return status
|
||||
|
||||
def set_pim_port_use_bus(pim_idx):
|
||||
|
||||
global pim_port_use_bus
|
||||
global oom_i2c_bus_table
|
||||
|
||||
if pim_port_use_bus[pim_idx]!=0:
|
||||
return 0
|
||||
|
||||
pim_port_use_bus[pim_idx]=oom_i2c_bus_table
|
||||
oom_i2c_bus_table=oom_i2c_bus_table+1
|
||||
|
||||
return pim_port_use_bus[pim_idx]
|
||||
|
||||
|
||||
def del_pim_port_use_bus(pim_idx):
|
||||
global oom_i2c_bus_table
|
||||
|
||||
oom_i2c_bus_table=oom_i2c_bus_table-1
|
||||
pim_port_use_bus[pim_idx]=0
|
||||
|
||||
|
||||
def device_remove():
|
||||
cmd1 = "echo 0x%x > /sys/bus/i2c/devices/i2c-%d/delete_device"
|
||||
|
||||
for bus in range(2, 10):
|
||||
#ret=check_pca_active(0x72, bus)
|
||||
#if ret==0:
|
||||
|
||||
cmdm= cmd1 % (0x72, bus)
|
||||
status, output = commands.getstatusoutput(cmdm)
|
||||
print "Remove %d-0072 i2c device"%bus
|
||||
cmdm= cmd1 % (0x71, bus)
|
||||
status, output = commands.getstatusoutput(cmdm)
|
||||
print "Remove %d-0071 i2c device"%bus
|
||||
|
||||
cmd="rm -f /usr/local/bin/minipack_qsfp/port*"
|
||||
status, output=log_os_system(cmd)
|
||||
return status
|
||||
|
||||
class device_monitor(object):
|
||||
|
||||
PIM_STATE_REMOVE = 0
|
||||
PIM_STATE_INSERT = 1
|
||||
PIM_STATE_IDLE=2
|
||||
|
||||
def __init__(self, log_file, log_level):
|
||||
"""Needs a logger and a logger level."""
|
||||
# set up logging to file
|
||||
logging.basicConfig(
|
||||
filename=log_file,
|
||||
filemode='w',
|
||||
level=log_level,
|
||||
format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s',
|
||||
datefmt='%H:%M:%S'
|
||||
)
|
||||
# set up logging to console
|
||||
if log_level == logging.DEBUG:
|
||||
console = logging.StreamHandler()
|
||||
console.setLevel(log_level)
|
||||
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
|
||||
console.setFormatter(formatter)
|
||||
logging.getLogger('').addHandler(console)
|
||||
|
||||
sys_handler = handler = logging.handlers.SysLogHandler(address = '/dev/log')
|
||||
sys_handler.setLevel(logging.WARNING)
|
||||
logging.getLogger('').addHandler(sys_handler)
|
||||
|
||||
#logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level)
|
||||
|
||||
def manage_pim(self):
|
||||
global pim_dev
|
||||
global pim_state
|
||||
|
||||
for pim_idx in range(PIM_MIN, PIM_MAX):
|
||||
presence=pim_dev.get_pim_presence(pim_idx)
|
||||
if presence==1:
|
||||
if pim_state[pim_idx]!=self.PIM_STATE_INSERT:
|
||||
#find which i2c_device can use. It start from 2
|
||||
i2c_bus_order=set_pim_port_use_bus(pim_idx)
|
||||
if i2c_bus_order==0:
|
||||
logging.info("pim_state[%d] PIM_STATE_INSERT", pim_idx);
|
||||
pim_state[pim_idx]=self.PIM_STATE_INSERT
|
||||
continue
|
||||
|
||||
logging.info ("pim_idx=%d oom use i2c_bus_order=%d", pim_idx, i2c_bus_order)
|
||||
ready=0
|
||||
retry_limit=100
|
||||
retry_count=0
|
||||
while retry_count < retry_limit:
|
||||
ret=check_pca_active(0x72, pim_idx+2)
|
||||
if ret==0:
|
||||
ready=1
|
||||
break
|
||||
retry_count=retry_count+1
|
||||
time.sleep(0.2)
|
||||
|
||||
if ready==1:
|
||||
status=pca9548_sysfs(pim_idx+2, 1)
|
||||
if status:
|
||||
status=pca9548_sysfs(pim_idx+2, 0) #del pca i2c device, give up set oom at this time.
|
||||
del_pim_port_use_bus(pim_idx)
|
||||
continue
|
||||
status=qsfp_eeprom_sys(pim_idx,i2c_bus_order, 1)
|
||||
if status:
|
||||
status=pca9548_sysfs(pim_idx+2, 0) #del pca i2c device, give up set oom at this time.
|
||||
del_pim_port_use_bus(pim_idx)
|
||||
continue
|
||||
#ret_2=check_pca_active(0x72, pim_idx+2)
|
||||
#ret_1=check_pca_active(0x71, pim_idx+2)
|
||||
|
||||
pim_state[pim_idx]=self.PIM_STATE_INSERT
|
||||
logging.info("pim_state[%d] PIM_STATE_INSERT", pim_idx);
|
||||
else:
|
||||
print "retry check 100 times for check pca addr"
|
||||
del_pim_port_use_bus(pim_idx)
|
||||
else:
|
||||
if pim_state[pim_idx]==self.PIM_STATE_INSERT:
|
||||
#pca9548_sysfs(pim_idx+2, 0)
|
||||
pim_state[pim_idx]=self.PIM_STATE_REMOVE
|
||||
logging.info("pim_state[%d] PIM_STATE_REMOVE", pim_idx);
|
||||
|
||||
def main(argv):
|
||||
log_file = '%s.log' % FUNCTION_NAME
|
||||
log_level = logging.INFO
|
||||
remove_dev=0
|
||||
cpu_pca_i2c_ready=0
|
||||
|
||||
if len(sys.argv) != 1:
|
||||
try:
|
||||
opts, args = getopt.getopt(argv,'hdlr',['lfile='])
|
||||
except getopt.GetoptError:
|
||||
print 'A:Usage: %s [-d] [-l <log_file>]' % sys.argv[0]
|
||||
return 0
|
||||
for opt, arg in opts:
|
||||
if opt == '-h':
|
||||
print 'B:Usage: %s [-d] [-l <log_file>]' % sys.argv[0]
|
||||
return 0
|
||||
elif opt in ('-d', '--debug'):
|
||||
log_level = logging.DEBUG
|
||||
elif opt in ('-l', '--lfile'):
|
||||
log_file = arg
|
||||
elif opt in ('-r', '--remove'):
|
||||
remove_dev=1
|
||||
|
||||
if remove_dev==1:
|
||||
device_remove()
|
||||
return 0
|
||||
monitor = device_monitor(log_file, log_level)
|
||||
global pim_dev
|
||||
pim_dev.init_pim_fpga()
|
||||
|
||||
while cpu_pca_i2c_ready==0:
|
||||
status=check_pca_active(0x70, 1)
|
||||
time.sleep(0.5)
|
||||
if status==0:
|
||||
cpu_pca_i2c_ready=1
|
||||
print "Make sure CPU pca i2c device is ready"
|
||||
break
|
||||
|
||||
while True:
|
||||
monitor.manage_pim()
|
||||
time.sleep(2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv[1:])
|
Loading…
Reference in New Issue
Block a user