|
4 | 4 | #
|
5 | 5 |
|
6 | 6 | try:
|
| 7 | + import os |
| 8 | + import logging |
7 | 9 | import time
|
| 10 | + import select |
8 | 11 | from sonic_sfp.sfputilbase import SfpUtilBase
|
9 | 12 | except ImportError as e:
|
10 | 13 | raise ImportError("%s - required module not found" % str(e))
|
@@ -337,3 +340,70 @@ def reset(self, port_num):
|
337 | 340 | reg_file.close()
|
338 | 341 |
|
339 | 342 | return True
|
| 343 | + |
| 344 | + def get_register(self, reg_file): |
| 345 | + retval = 'ERR' |
| 346 | + |
| 347 | + if (not os.path.isfile(reg_file)): |
| 348 | + print reg_file, 'not found !' |
| 349 | + return retval |
| 350 | + |
| 351 | + try: |
| 352 | + with open(reg_file, 'r') as fd: |
| 353 | + retval = fd.read() |
| 354 | + except Exception as error: |
| 355 | + logging.error("Unable to open ", reg_file, "file !") |
| 356 | + |
| 357 | + retval = retval.rstrip('\r\n') |
| 358 | + retval = retval.lstrip(" ") |
| 359 | + return retval |
| 360 | + |
| 361 | + def get_transceiver_change_event(self, timeout=0): |
| 362 | + epoll = select.epoll() |
| 363 | + port_dict = {} |
| 364 | + try: |
| 365 | + # We get notified when there is an SCI interrupt from GPIO SUS6 |
| 366 | + fd = open("/sys/devices/platform/dell_ich.0/sci_int_gpio_sus6", "r") |
| 367 | + epoll.register(fd.fileno(), select.EPOLLIN) |
| 368 | + events = epoll.poll(timeout=timeout if timeout != 0 else -1) |
| 369 | + if events: |
| 370 | + # Read the QSFP ABS interrupt & status registers |
| 371 | + cpld2_abs_int = self.get_register("/sys/class/i2c-adapter/i2c-14/14-003e/qsfp_abs_int") |
| 372 | + cpld2_abs_sta = self.get_register("/sys/class/i2c-adapter/i2c-14/14-003e/qsfp_abs_sta") |
| 373 | + cpld3_abs_int = self.get_register("/sys/class/i2c-adapter/i2c-15/15-003e/qsfp_abs_int") |
| 374 | + cpld3_abs_sta = self.get_register("/sys/class/i2c-adapter/i2c-15/15-003e/qsfp_abs_sta") |
| 375 | + cpld4_abs_int = self.get_register("/sys/class/i2c-adapter/i2c-16/16-003e/qsfp_abs_int") |
| 376 | + cpld4_abs_sta = self.get_register("/sys/class/i2c-adapter/i2c-16/16-003e/qsfp_abs_sta") |
| 377 | + |
| 378 | + if (cpld2_abs_int == 'ERR' or cpld2_abs_sta == 'ERR' or \ |
| 379 | + cpld3_abs_int == 'ERR' or cpld3_abs_sta == 'ERR' or \ |
| 380 | + cpld4_abs_int == 'ERR' or cpld4_abs_sta == 'ERR' ): |
| 381 | + return False, {} |
| 382 | + |
| 383 | + cpld2_abs_int = int(cpld2_abs_int, 16) |
| 384 | + cpld2_abs_sta = int(cpld2_abs_sta, 16) |
| 385 | + cpld3_abs_int = int(cpld3_abs_int, 16) |
| 386 | + cpld3_abs_sta = int(cpld3_abs_sta, 16) |
| 387 | + cpld4_abs_int = int(cpld4_abs_int, 16) |
| 388 | + cpld4_abs_sta = int(cpld4_abs_sta, 16) |
| 389 | + |
| 390 | + # Make it contiguous (discard reserved bits) |
| 391 | + interrupt_reg = (cpld2_abs_int & 0xfff) | ((cpld3_abs_int & 0x3ff) << 12) | ((cpld4_abs_int & 0x3ff) << 22) |
| 392 | + status_reg = (cpld2_abs_sta & 0xfff) | ((cpld3_abs_sta & 0x3ff) << 12) | ((cpld4_abs_sta & 0x3ff) << 22) |
| 393 | + |
| 394 | + port=self.port_start |
| 395 | + while port <= self.port_end: |
| 396 | + if interrupt_reg & (1<<port)): |
| 397 | + if status_reg & (1<<port)): |
| 398 | + # status reg 1 => optics is removed |
| 399 | + port_dict[port] = '0' |
| 400 | + else: |
| 401 | + # status reg 0 => optics is inserted |
| 402 | + port_dict[port] = '1' |
| 403 | + port += 1 |
| 404 | + return True, port_dict |
| 405 | + finally: |
| 406 | + fd.close() |
| 407 | + epoll.close() |
| 408 | + |
| 409 | + return False, {} |
0 commit comments