diff --git a/device/accton/x86_64-accton_as5712_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as5712_54x-r0/plugins/sfputil.py index 9eee5b99fbd0..7c585ab2d6ef 100755 --- a/device/accton/x86_64-accton_as5712_54x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as5712_54x-r0/plugins/sfputil.py @@ -2,9 +2,9 @@ # # Platform-specific SFP transceiver interface for SONiC # - try: import time + import os from sonic_sfp.sfputilbase import SfpUtilBase except ImportError as e: raise ImportError("%s - required module not found" % str(e)) @@ -21,8 +21,14 @@ class SfpUtil(SfpUtilBase): BASE_VAL_PATH = "/sys/class/i2c-adapter/i2c-{0}/{1}-0050/" BASE_OOM_PATH = "/sys/bus/i2c/devices/{0}-0050/" - BASE_CPLD2_PATH = "/sys/bus/i2c/devices/0-0061/" - BASE_CPLD3_PATH = "/sys/bus/i2c/devices/0-0062/" + BASE_CPLD2_PATH = "/sys/bus/i2c/devices/{0}-0061/" + BASE_CPLD3_PATH = "/sys/bus/i2c/devices/{0}-0062/" + I2C_BUS_ORDER = -1 + + #The sidebands of QSFP is different. + #present is in-order. + #But lp_mode and reset are not. + qsfp_sb_map = [1, 3, 5, 2, 4, 6] _port_to_is_present = {} _port_to_lp_mode = {} @@ -137,18 +143,30 @@ def __init__(self): SfpUtilBase.__init__(self) + #Two i2c buses might get flipped order, check them both. + def update_i2c_order(self): + if self.I2C_BUS_ORDER < 0: + eeprom_path = "/sys/bus/i2c/devices/1-0057/eeprom" + if os.path.exists(eeprom_path): + self.I2C_BUS_ORDER = 0 + eeprom_path = "/sys/bus/i2c/devices/0-0057/eeprom" + if os.path.exists(eeprom_path): + self.I2C_BUS_ORDER = 1 + return self.I2C_BUS_ORDER + 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 + order = self.update_i2c_order() if port_num < 24: - present_path = self.BASE_CPLD2_PATH + "module_present_" + str(self._port_to_i2c_mapping[port_num][0]) + present_path = self.BASE_CPLD2_PATH.format(order) else: - present_path = self.BASE_CPLD3_PATH + "module_present_" + str(self._port_to_i2c_mapping[port_num][0]) + present_path = self.BASE_CPLD3_PATH.format(order) + present_path = present_path + "module_present_" + str(self._port_to_i2c_mapping[port_num][0]) self.__port_to_is_present = present_path - try: val_file = open(self.__port_to_is_present) @@ -165,11 +183,21 @@ def get_presence(self, port_num): return False + def qsfp_sb_remap(self, port_num): + qsfp_start = self.qsfp_port_start + qsfp_index = self._port_to_i2c_mapping[port_num][0] - qsfp_start + qsfp_index = self.qsfp_sb_map[qsfp_index-1] + return qsfp_start+qsfp_index + def get_low_power_mode(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - lp_mode_path = self.BASE_CPLD3_PATH + "module_lp_mode_" + str(self._port_to_i2c_mapping[port_num][0]) + order = self.update_i2c_order() + lp_mode_path = self.BASE_CPLD3_PATH.format(order) + lp_mode_path = lp_mode_path + "module_lp_mode_" + q = self.qsfp_sb_remap(port_num) + lp_mode_path = lp_mode_path + str(q) try: val_file = open(lp_mode_path) @@ -190,7 +218,11 @@ def set_low_power_mode(self, port_num, lpmode): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - lp_mode_path = self.BASE_CPLD3_PATH + "module_lp_mode_" + str(self._port_to_i2c_mapping[port_num][0]) + order = self.update_i2c_order() + lp_mode_path = self.BASE_CPLD3_PATH.format(order) + lp_mode_path = lp_mode_path + "module_lp_mode_" + q = self.qsfp_sb_remap(port_num) + lp_mode_path = lp_mode_path + str(q) try: reg_file = open(lp_mode_path, 'r+') @@ -212,7 +244,11 @@ def reset(self, port_num): if port_num < self.qsfp_port_start or port_num > self.qsfp_port_end: return False - mod_rst_path = lp_mode_path = self.BASE_CPLD3_PATH + "module_reset_" + str(self._port_to_i2c_mapping[port_num][0]) + order = self.update_i2c_order() + lp_mode_path = self.BASE_CPLD3_PATH.format(order) + mod_rst_path = lp_mode_path + "module_reset_" + q = self.qsfp_sb_remap(port_num) + mod_rst_path = mod_rst_path + str(q) try: reg_file = open(mod_rst_path, 'r+') @@ -220,13 +256,15 @@ def reset(self, port_num): print "Error: unable to open file: %s" % str(e) return False - reg_value = '1' - - reg_file.write(reg_value) + #toggle reset + reg_file.seek(0) + reg_file.write('0') + time.sleep(1) + reg_file.seek(0) + reg_file.write('1') reg_file.close() - return True - + def get_transceiver_change_event(self): """ TODO: This function need to be implemented @@ -234,3 +272,4 @@ def get_transceiver_change_event(self): on this platform. """ raise NotImplementedError + diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/i2c-mux-accton_as5712_54x_cpld.c b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/i2c-mux-accton_as5712_54x_cpld.c index d63cb14b5a67..ed097e6b30e8 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/i2c-mux-accton_as5712_54x_cpld.c +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/modules/i2c-mux-accton_as5712_54x_cpld.c @@ -1,33 +1,31 @@ /* - * I2C multiplexer + * An I2C multiplexer dirver for accton as5712 CPLD * - * Copyright (C) Brandon Chuang + * Copyright (C) 2015 Accton Technology Corporation. + * Brandon Chuang * * This module supports the accton cpld that hold the channel select * mechanism for other i2c slave devices, such as SFP. * This includes the: - * Accton as5712_54x CPLD1/CPLD2/CPLD3 + * Accton as5712_54x CPLD1/CPLD2/CPLD3 * * Based on: - * pca954x.c from Kumar Gala + * pca954x.c from Kumar Gala * Copyright (C) 2006 * * Based on: - * pca954x.c from Ken Harrenstien + * pca954x.c from Ken Harrenstien * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) * * Based on: - * i2c-virtual_cb.c from Brian Kuschak + * i2c-virtual_cb.c from Brian Kuschak * and - * pca9540.c from Jean Delvare . + * pca9540.c from Jean Delvare . * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any * warranty of any kind, whether express or implied. */ -#if 0 -#define DEBUG -#endif #include #include @@ -40,8 +38,8 @@ #include #include -#define I2C_RW_RETRY_COUNT 10 -#define I2C_RW_RETRY_INTERVAL 60 /* ms */ +#define I2C_RW_RETRY_COUNT 10 +#define I2C_RW_RETRY_INTERVAL 60 /* ms */ #define NUM_OF_CPLD1_CHANS 0x0 #define NUM_OF_CPLD2_CHANS 0x18 @@ -49,12 +47,6 @@ #define CPLD_CHANNEL_SELECT_REG 0x2 #define CPLD_DESELECT_CHANNEL 0xFF -#if 0 -#define NUM_OF_ALL_CPLD_CHANS (NUM_OF_CPLD2_CHANS + NUM_OF_CPLD3_CHANS) -#endif - -#define ACCTON_I2C_CPLD_MUX_MAX_NCHANS NUM_OF_CPLD3_CHANS - static LIST_HEAD(cpld_client_list); static struct mutex list_lock; @@ -71,24 +63,13 @@ enum cpld_mux_type { struct as5712_54x_cpld_data { enum cpld_mux_type type; - struct i2c_adapter *virt_adaps[ACCTON_I2C_CPLD_MUX_MAX_NCHANS]; - u8 last_chan; /* last register value */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) struct i2c_client *client; - struct i2c_mux_core *muxc; -#endif + u8 last_chan; /* last register value */ + struct device *hwmon_dev; struct mutex update_lock; }; -#if 0 -/* The mapping table between mux index and adapter index - array index : the mux index - the content : adapter index - */ -static int mux_adap_map[NUM_OF_ALL_CPLD_CHANS]; -#endif - struct chip_desc { u8 nchans; u8 deselectChan; @@ -97,16 +78,16 @@ struct chip_desc { /* Provide specs for the PCA954x types we know about */ static const struct chip_desc chips[] = { [as5712_54x_cpld1] = { - .nchans = NUM_OF_CPLD1_CHANS, - .deselectChan = CPLD_DESELECT_CHANNEL, + .nchans = NUM_OF_CPLD1_CHANS, + .deselectChan = CPLD_DESELECT_CHANNEL, }, [as5712_54x_cpld2] = { - .nchans = NUM_OF_CPLD2_CHANS, - .deselectChan = CPLD_DESELECT_CHANNEL, + .nchans = NUM_OF_CPLD2_CHANS, + .deselectChan = CPLD_DESELECT_CHANNEL, }, [as5712_54x_cpld3] = { - .nchans = NUM_OF_CPLD3_CHANS, - .deselectChan = CPLD_DESELECT_CHANNEL, + .nchans = NUM_OF_CPLD3_CHANS, + .deselectChan = CPLD_DESELECT_CHANNEL, } }; @@ -118,229 +99,215 @@ static const struct i2c_device_id as5712_54x_cpld_mux_id[] = { }; MODULE_DEVICE_TABLE(i2c, as5712_54x_cpld_mux_id); -#define TRANSCEIVER_PRESENT_ATTR_ID(index) MODULE_PRESENT_##index -#define TRANSCEIVER_TXDISABLE_ATTR_ID(index) MODULE_TXDISABLE_##index -#define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index -#define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index -#define TRANSCEIVER_LPMODE_ATTR_ID(index) MODULE_LPMODE_##index -#define TRANSCEIVER_RESET_ATTR_ID(index) MODULE_RESET_##index +#define TRANSCEIVER_PRESENT_ATTR_ID(index) MODULE_PRESENT_##index +#define TRANSCEIVER_TXDISABLE_ATTR_ID(index) MODULE_TXDISABLE_##index +#define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index +#define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index enum as5712_54x_cpld1_sysfs_attributes { - CPLD_VERSION, - ACCESS, - MODULE_PRESENT_ALL, - MODULE_RXLOS_ALL, - /* transceiver attributes */ - TRANSCEIVER_PRESENT_ATTR_ID(1), - TRANSCEIVER_PRESENT_ATTR_ID(2), - TRANSCEIVER_PRESENT_ATTR_ID(3), - TRANSCEIVER_PRESENT_ATTR_ID(4), - TRANSCEIVER_PRESENT_ATTR_ID(5), - TRANSCEIVER_PRESENT_ATTR_ID(6), - TRANSCEIVER_PRESENT_ATTR_ID(7), - TRANSCEIVER_PRESENT_ATTR_ID(8), - TRANSCEIVER_PRESENT_ATTR_ID(9), - TRANSCEIVER_PRESENT_ATTR_ID(10), - TRANSCEIVER_PRESENT_ATTR_ID(11), - TRANSCEIVER_PRESENT_ATTR_ID(12), - TRANSCEIVER_PRESENT_ATTR_ID(13), - TRANSCEIVER_PRESENT_ATTR_ID(14), - TRANSCEIVER_PRESENT_ATTR_ID(15), - TRANSCEIVER_PRESENT_ATTR_ID(16), - TRANSCEIVER_PRESENT_ATTR_ID(17), - TRANSCEIVER_PRESENT_ATTR_ID(18), - TRANSCEIVER_PRESENT_ATTR_ID(19), - TRANSCEIVER_PRESENT_ATTR_ID(20), - TRANSCEIVER_PRESENT_ATTR_ID(21), - TRANSCEIVER_PRESENT_ATTR_ID(22), - TRANSCEIVER_PRESENT_ATTR_ID(23), - TRANSCEIVER_PRESENT_ATTR_ID(24), - TRANSCEIVER_PRESENT_ATTR_ID(25), - TRANSCEIVER_PRESENT_ATTR_ID(26), - TRANSCEIVER_PRESENT_ATTR_ID(27), - TRANSCEIVER_PRESENT_ATTR_ID(28), - TRANSCEIVER_PRESENT_ATTR_ID(29), - TRANSCEIVER_PRESENT_ATTR_ID(30), - TRANSCEIVER_PRESENT_ATTR_ID(31), - TRANSCEIVER_PRESENT_ATTR_ID(32), - TRANSCEIVER_PRESENT_ATTR_ID(33), - TRANSCEIVER_PRESENT_ATTR_ID(34), - TRANSCEIVER_PRESENT_ATTR_ID(35), - TRANSCEIVER_PRESENT_ATTR_ID(36), - TRANSCEIVER_PRESENT_ATTR_ID(37), - TRANSCEIVER_PRESENT_ATTR_ID(38), - TRANSCEIVER_PRESENT_ATTR_ID(39), - TRANSCEIVER_PRESENT_ATTR_ID(40), - TRANSCEIVER_PRESENT_ATTR_ID(41), - TRANSCEIVER_PRESENT_ATTR_ID(42), - TRANSCEIVER_PRESENT_ATTR_ID(43), - TRANSCEIVER_PRESENT_ATTR_ID(44), - TRANSCEIVER_PRESENT_ATTR_ID(45), - TRANSCEIVER_PRESENT_ATTR_ID(46), - TRANSCEIVER_PRESENT_ATTR_ID(47), - TRANSCEIVER_PRESENT_ATTR_ID(48), - TRANSCEIVER_PRESENT_ATTR_ID(49), - TRANSCEIVER_PRESENT_ATTR_ID(50), - TRANSCEIVER_PRESENT_ATTR_ID(51), - TRANSCEIVER_PRESENT_ATTR_ID(52), - TRANSCEIVER_PRESENT_ATTR_ID(53), - TRANSCEIVER_PRESENT_ATTR_ID(54), - TRANSCEIVER_TXDISABLE_ATTR_ID(1), - TRANSCEIVER_TXDISABLE_ATTR_ID(2), - TRANSCEIVER_TXDISABLE_ATTR_ID(3), - TRANSCEIVER_TXDISABLE_ATTR_ID(4), - TRANSCEIVER_TXDISABLE_ATTR_ID(5), - TRANSCEIVER_TXDISABLE_ATTR_ID(6), - TRANSCEIVER_TXDISABLE_ATTR_ID(7), - TRANSCEIVER_TXDISABLE_ATTR_ID(8), - TRANSCEIVER_TXDISABLE_ATTR_ID(9), - TRANSCEIVER_TXDISABLE_ATTR_ID(10), - TRANSCEIVER_TXDISABLE_ATTR_ID(11), - TRANSCEIVER_TXDISABLE_ATTR_ID(12), - TRANSCEIVER_TXDISABLE_ATTR_ID(13), - TRANSCEIVER_TXDISABLE_ATTR_ID(14), - TRANSCEIVER_TXDISABLE_ATTR_ID(15), - TRANSCEIVER_TXDISABLE_ATTR_ID(16), - TRANSCEIVER_TXDISABLE_ATTR_ID(17), - TRANSCEIVER_TXDISABLE_ATTR_ID(18), - TRANSCEIVER_TXDISABLE_ATTR_ID(19), - TRANSCEIVER_TXDISABLE_ATTR_ID(20), - TRANSCEIVER_TXDISABLE_ATTR_ID(21), - TRANSCEIVER_TXDISABLE_ATTR_ID(22), - TRANSCEIVER_TXDISABLE_ATTR_ID(23), - TRANSCEIVER_TXDISABLE_ATTR_ID(24), - TRANSCEIVER_TXDISABLE_ATTR_ID(25), - TRANSCEIVER_TXDISABLE_ATTR_ID(26), - TRANSCEIVER_TXDISABLE_ATTR_ID(27), - TRANSCEIVER_TXDISABLE_ATTR_ID(28), - TRANSCEIVER_TXDISABLE_ATTR_ID(29), - TRANSCEIVER_TXDISABLE_ATTR_ID(30), - TRANSCEIVER_TXDISABLE_ATTR_ID(31), - TRANSCEIVER_TXDISABLE_ATTR_ID(32), - TRANSCEIVER_TXDISABLE_ATTR_ID(33), - TRANSCEIVER_TXDISABLE_ATTR_ID(34), - TRANSCEIVER_TXDISABLE_ATTR_ID(35), - TRANSCEIVER_TXDISABLE_ATTR_ID(36), - TRANSCEIVER_TXDISABLE_ATTR_ID(37), - TRANSCEIVER_TXDISABLE_ATTR_ID(38), - TRANSCEIVER_TXDISABLE_ATTR_ID(39), - TRANSCEIVER_TXDISABLE_ATTR_ID(40), - TRANSCEIVER_TXDISABLE_ATTR_ID(41), - TRANSCEIVER_TXDISABLE_ATTR_ID(42), - TRANSCEIVER_TXDISABLE_ATTR_ID(43), - TRANSCEIVER_TXDISABLE_ATTR_ID(44), - TRANSCEIVER_TXDISABLE_ATTR_ID(45), - TRANSCEIVER_TXDISABLE_ATTR_ID(46), - TRANSCEIVER_TXDISABLE_ATTR_ID(47), - TRANSCEIVER_TXDISABLE_ATTR_ID(48), - TRANSCEIVER_RXLOS_ATTR_ID(1), - TRANSCEIVER_RXLOS_ATTR_ID(2), - TRANSCEIVER_RXLOS_ATTR_ID(3), - TRANSCEIVER_RXLOS_ATTR_ID(4), - TRANSCEIVER_RXLOS_ATTR_ID(5), - TRANSCEIVER_RXLOS_ATTR_ID(6), - TRANSCEIVER_RXLOS_ATTR_ID(7), - TRANSCEIVER_RXLOS_ATTR_ID(8), - TRANSCEIVER_RXLOS_ATTR_ID(9), - TRANSCEIVER_RXLOS_ATTR_ID(10), - TRANSCEIVER_RXLOS_ATTR_ID(11), - TRANSCEIVER_RXLOS_ATTR_ID(12), - TRANSCEIVER_RXLOS_ATTR_ID(13), - TRANSCEIVER_RXLOS_ATTR_ID(14), - TRANSCEIVER_RXLOS_ATTR_ID(15), - TRANSCEIVER_RXLOS_ATTR_ID(16), - TRANSCEIVER_RXLOS_ATTR_ID(17), - TRANSCEIVER_RXLOS_ATTR_ID(18), - TRANSCEIVER_RXLOS_ATTR_ID(19), - TRANSCEIVER_RXLOS_ATTR_ID(20), - TRANSCEIVER_RXLOS_ATTR_ID(21), - TRANSCEIVER_RXLOS_ATTR_ID(22), - TRANSCEIVER_RXLOS_ATTR_ID(23), - TRANSCEIVER_RXLOS_ATTR_ID(24), - TRANSCEIVER_RXLOS_ATTR_ID(25), - TRANSCEIVER_RXLOS_ATTR_ID(26), - TRANSCEIVER_RXLOS_ATTR_ID(27), - TRANSCEIVER_RXLOS_ATTR_ID(28), - TRANSCEIVER_RXLOS_ATTR_ID(29), - TRANSCEIVER_RXLOS_ATTR_ID(30), - TRANSCEIVER_RXLOS_ATTR_ID(31), - TRANSCEIVER_RXLOS_ATTR_ID(32), - TRANSCEIVER_RXLOS_ATTR_ID(33), - TRANSCEIVER_RXLOS_ATTR_ID(34), - TRANSCEIVER_RXLOS_ATTR_ID(35), - TRANSCEIVER_RXLOS_ATTR_ID(36), - TRANSCEIVER_RXLOS_ATTR_ID(37), - TRANSCEIVER_RXLOS_ATTR_ID(38), - TRANSCEIVER_RXLOS_ATTR_ID(39), - TRANSCEIVER_RXLOS_ATTR_ID(40), - TRANSCEIVER_RXLOS_ATTR_ID(41), - TRANSCEIVER_RXLOS_ATTR_ID(42), - TRANSCEIVER_RXLOS_ATTR_ID(43), - TRANSCEIVER_RXLOS_ATTR_ID(44), - TRANSCEIVER_RXLOS_ATTR_ID(45), - TRANSCEIVER_RXLOS_ATTR_ID(46), - TRANSCEIVER_RXLOS_ATTR_ID(47), - TRANSCEIVER_RXLOS_ATTR_ID(48), - TRANSCEIVER_TXFAULT_ATTR_ID(1), - TRANSCEIVER_TXFAULT_ATTR_ID(2), - TRANSCEIVER_TXFAULT_ATTR_ID(3), - TRANSCEIVER_TXFAULT_ATTR_ID(4), - TRANSCEIVER_TXFAULT_ATTR_ID(5), - TRANSCEIVER_TXFAULT_ATTR_ID(6), - TRANSCEIVER_TXFAULT_ATTR_ID(7), - TRANSCEIVER_TXFAULT_ATTR_ID(8), - TRANSCEIVER_TXFAULT_ATTR_ID(9), - TRANSCEIVER_TXFAULT_ATTR_ID(10), - TRANSCEIVER_TXFAULT_ATTR_ID(11), - TRANSCEIVER_TXFAULT_ATTR_ID(12), - TRANSCEIVER_TXFAULT_ATTR_ID(13), - TRANSCEIVER_TXFAULT_ATTR_ID(14), - TRANSCEIVER_TXFAULT_ATTR_ID(15), - TRANSCEIVER_TXFAULT_ATTR_ID(16), - TRANSCEIVER_TXFAULT_ATTR_ID(17), - TRANSCEIVER_TXFAULT_ATTR_ID(18), - TRANSCEIVER_TXFAULT_ATTR_ID(19), - TRANSCEIVER_TXFAULT_ATTR_ID(20), - TRANSCEIVER_TXFAULT_ATTR_ID(21), - TRANSCEIVER_TXFAULT_ATTR_ID(22), - TRANSCEIVER_TXFAULT_ATTR_ID(23), - TRANSCEIVER_TXFAULT_ATTR_ID(24), - TRANSCEIVER_TXFAULT_ATTR_ID(25), - TRANSCEIVER_TXFAULT_ATTR_ID(26), - TRANSCEIVER_TXFAULT_ATTR_ID(27), - TRANSCEIVER_TXFAULT_ATTR_ID(28), - TRANSCEIVER_TXFAULT_ATTR_ID(29), - TRANSCEIVER_TXFAULT_ATTR_ID(30), - TRANSCEIVER_TXFAULT_ATTR_ID(31), - TRANSCEIVER_TXFAULT_ATTR_ID(32), - TRANSCEIVER_TXFAULT_ATTR_ID(33), - TRANSCEIVER_TXFAULT_ATTR_ID(34), - TRANSCEIVER_TXFAULT_ATTR_ID(35), - TRANSCEIVER_TXFAULT_ATTR_ID(36), - TRANSCEIVER_TXFAULT_ATTR_ID(37), - TRANSCEIVER_TXFAULT_ATTR_ID(38), - TRANSCEIVER_TXFAULT_ATTR_ID(39), - TRANSCEIVER_TXFAULT_ATTR_ID(40), - TRANSCEIVER_TXFAULT_ATTR_ID(41), - TRANSCEIVER_TXFAULT_ATTR_ID(42), - TRANSCEIVER_TXFAULT_ATTR_ID(43), - TRANSCEIVER_TXFAULT_ATTR_ID(44), - TRANSCEIVER_TXFAULT_ATTR_ID(45), - TRANSCEIVER_TXFAULT_ATTR_ID(46), - TRANSCEIVER_TXFAULT_ATTR_ID(47), - TRANSCEIVER_TXFAULT_ATTR_ID(48), - TRANSCEIVER_LPMODE_ATTR_ID(49), - TRANSCEIVER_LPMODE_ATTR_ID(50), - TRANSCEIVER_LPMODE_ATTR_ID(51), - TRANSCEIVER_LPMODE_ATTR_ID(52), - TRANSCEIVER_LPMODE_ATTR_ID(53), - TRANSCEIVER_LPMODE_ATTR_ID(54), - TRANSCEIVER_RESET_ATTR_ID(49), - TRANSCEIVER_RESET_ATTR_ID(50), - TRANSCEIVER_RESET_ATTR_ID(51), - TRANSCEIVER_RESET_ATTR_ID(52), - TRANSCEIVER_RESET_ATTR_ID(53), - TRANSCEIVER_RESET_ATTR_ID(54), + CPLD_VERSION, + ACCESS, + MODULE_PRESENT_ALL, + MODULE_RXLOS_ALL, + /* transceiver attributes */ + TRANSCEIVER_PRESENT_ATTR_ID(1), + TRANSCEIVER_PRESENT_ATTR_ID(2), + TRANSCEIVER_PRESENT_ATTR_ID(3), + TRANSCEIVER_PRESENT_ATTR_ID(4), + TRANSCEIVER_PRESENT_ATTR_ID(5), + TRANSCEIVER_PRESENT_ATTR_ID(6), + TRANSCEIVER_PRESENT_ATTR_ID(7), + TRANSCEIVER_PRESENT_ATTR_ID(8), + TRANSCEIVER_PRESENT_ATTR_ID(9), + TRANSCEIVER_PRESENT_ATTR_ID(10), + TRANSCEIVER_PRESENT_ATTR_ID(11), + TRANSCEIVER_PRESENT_ATTR_ID(12), + TRANSCEIVER_PRESENT_ATTR_ID(13), + TRANSCEIVER_PRESENT_ATTR_ID(14), + TRANSCEIVER_PRESENT_ATTR_ID(15), + TRANSCEIVER_PRESENT_ATTR_ID(16), + TRANSCEIVER_PRESENT_ATTR_ID(17), + TRANSCEIVER_PRESENT_ATTR_ID(18), + TRANSCEIVER_PRESENT_ATTR_ID(19), + TRANSCEIVER_PRESENT_ATTR_ID(20), + TRANSCEIVER_PRESENT_ATTR_ID(21), + TRANSCEIVER_PRESENT_ATTR_ID(22), + TRANSCEIVER_PRESENT_ATTR_ID(23), + TRANSCEIVER_PRESENT_ATTR_ID(24), + TRANSCEIVER_PRESENT_ATTR_ID(25), + TRANSCEIVER_PRESENT_ATTR_ID(26), + TRANSCEIVER_PRESENT_ATTR_ID(27), + TRANSCEIVER_PRESENT_ATTR_ID(28), + TRANSCEIVER_PRESENT_ATTR_ID(29), + TRANSCEIVER_PRESENT_ATTR_ID(30), + TRANSCEIVER_PRESENT_ATTR_ID(31), + TRANSCEIVER_PRESENT_ATTR_ID(32), + TRANSCEIVER_PRESENT_ATTR_ID(33), + TRANSCEIVER_PRESENT_ATTR_ID(34), + TRANSCEIVER_PRESENT_ATTR_ID(35), + TRANSCEIVER_PRESENT_ATTR_ID(36), + TRANSCEIVER_PRESENT_ATTR_ID(37), + TRANSCEIVER_PRESENT_ATTR_ID(38), + TRANSCEIVER_PRESENT_ATTR_ID(39), + TRANSCEIVER_PRESENT_ATTR_ID(40), + TRANSCEIVER_PRESENT_ATTR_ID(41), + TRANSCEIVER_PRESENT_ATTR_ID(42), + TRANSCEIVER_PRESENT_ATTR_ID(43), + TRANSCEIVER_PRESENT_ATTR_ID(44), + TRANSCEIVER_PRESENT_ATTR_ID(45), + TRANSCEIVER_PRESENT_ATTR_ID(46), + TRANSCEIVER_PRESENT_ATTR_ID(47), + TRANSCEIVER_PRESENT_ATTR_ID(48), + TRANSCEIVER_PRESENT_ATTR_ID(49), + TRANSCEIVER_PRESENT_ATTR_ID(50), + TRANSCEIVER_PRESENT_ATTR_ID(51), + TRANSCEIVER_PRESENT_ATTR_ID(52), + TRANSCEIVER_PRESENT_ATTR_ID(53), + TRANSCEIVER_PRESENT_ATTR_ID(54), + TRANSCEIVER_TXDISABLE_ATTR_ID(1), + TRANSCEIVER_TXDISABLE_ATTR_ID(2), + TRANSCEIVER_TXDISABLE_ATTR_ID(3), + TRANSCEIVER_TXDISABLE_ATTR_ID(4), + TRANSCEIVER_TXDISABLE_ATTR_ID(5), + TRANSCEIVER_TXDISABLE_ATTR_ID(6), + TRANSCEIVER_TXDISABLE_ATTR_ID(7), + TRANSCEIVER_TXDISABLE_ATTR_ID(8), + TRANSCEIVER_TXDISABLE_ATTR_ID(9), + TRANSCEIVER_TXDISABLE_ATTR_ID(10), + TRANSCEIVER_TXDISABLE_ATTR_ID(11), + TRANSCEIVER_TXDISABLE_ATTR_ID(12), + TRANSCEIVER_TXDISABLE_ATTR_ID(13), + TRANSCEIVER_TXDISABLE_ATTR_ID(14), + TRANSCEIVER_TXDISABLE_ATTR_ID(15), + TRANSCEIVER_TXDISABLE_ATTR_ID(16), + TRANSCEIVER_TXDISABLE_ATTR_ID(17), + TRANSCEIVER_TXDISABLE_ATTR_ID(18), + TRANSCEIVER_TXDISABLE_ATTR_ID(19), + TRANSCEIVER_TXDISABLE_ATTR_ID(20), + TRANSCEIVER_TXDISABLE_ATTR_ID(21), + TRANSCEIVER_TXDISABLE_ATTR_ID(22), + TRANSCEIVER_TXDISABLE_ATTR_ID(23), + TRANSCEIVER_TXDISABLE_ATTR_ID(24), + TRANSCEIVER_TXDISABLE_ATTR_ID(25), + TRANSCEIVER_TXDISABLE_ATTR_ID(26), + TRANSCEIVER_TXDISABLE_ATTR_ID(27), + TRANSCEIVER_TXDISABLE_ATTR_ID(28), + TRANSCEIVER_TXDISABLE_ATTR_ID(29), + TRANSCEIVER_TXDISABLE_ATTR_ID(30), + TRANSCEIVER_TXDISABLE_ATTR_ID(31), + TRANSCEIVER_TXDISABLE_ATTR_ID(32), + TRANSCEIVER_TXDISABLE_ATTR_ID(33), + TRANSCEIVER_TXDISABLE_ATTR_ID(34), + TRANSCEIVER_TXDISABLE_ATTR_ID(35), + TRANSCEIVER_TXDISABLE_ATTR_ID(36), + TRANSCEIVER_TXDISABLE_ATTR_ID(37), + TRANSCEIVER_TXDISABLE_ATTR_ID(38), + TRANSCEIVER_TXDISABLE_ATTR_ID(39), + TRANSCEIVER_TXDISABLE_ATTR_ID(40), + TRANSCEIVER_TXDISABLE_ATTR_ID(41), + TRANSCEIVER_TXDISABLE_ATTR_ID(42), + TRANSCEIVER_TXDISABLE_ATTR_ID(43), + TRANSCEIVER_TXDISABLE_ATTR_ID(44), + TRANSCEIVER_TXDISABLE_ATTR_ID(45), + TRANSCEIVER_TXDISABLE_ATTR_ID(46), + TRANSCEIVER_TXDISABLE_ATTR_ID(47), + TRANSCEIVER_TXDISABLE_ATTR_ID(48), + TRANSCEIVER_RXLOS_ATTR_ID(1), + TRANSCEIVER_RXLOS_ATTR_ID(2), + TRANSCEIVER_RXLOS_ATTR_ID(3), + TRANSCEIVER_RXLOS_ATTR_ID(4), + TRANSCEIVER_RXLOS_ATTR_ID(5), + TRANSCEIVER_RXLOS_ATTR_ID(6), + TRANSCEIVER_RXLOS_ATTR_ID(7), + TRANSCEIVER_RXLOS_ATTR_ID(8), + TRANSCEIVER_RXLOS_ATTR_ID(9), + TRANSCEIVER_RXLOS_ATTR_ID(10), + TRANSCEIVER_RXLOS_ATTR_ID(11), + TRANSCEIVER_RXLOS_ATTR_ID(12), + TRANSCEIVER_RXLOS_ATTR_ID(13), + TRANSCEIVER_RXLOS_ATTR_ID(14), + TRANSCEIVER_RXLOS_ATTR_ID(15), + TRANSCEIVER_RXLOS_ATTR_ID(16), + TRANSCEIVER_RXLOS_ATTR_ID(17), + TRANSCEIVER_RXLOS_ATTR_ID(18), + TRANSCEIVER_RXLOS_ATTR_ID(19), + TRANSCEIVER_RXLOS_ATTR_ID(20), + TRANSCEIVER_RXLOS_ATTR_ID(21), + TRANSCEIVER_RXLOS_ATTR_ID(22), + TRANSCEIVER_RXLOS_ATTR_ID(23), + TRANSCEIVER_RXLOS_ATTR_ID(24), + TRANSCEIVER_RXLOS_ATTR_ID(25), + TRANSCEIVER_RXLOS_ATTR_ID(26), + TRANSCEIVER_RXLOS_ATTR_ID(27), + TRANSCEIVER_RXLOS_ATTR_ID(28), + TRANSCEIVER_RXLOS_ATTR_ID(29), + TRANSCEIVER_RXLOS_ATTR_ID(30), + TRANSCEIVER_RXLOS_ATTR_ID(31), + TRANSCEIVER_RXLOS_ATTR_ID(32), + TRANSCEIVER_RXLOS_ATTR_ID(33), + TRANSCEIVER_RXLOS_ATTR_ID(34), + TRANSCEIVER_RXLOS_ATTR_ID(35), + TRANSCEIVER_RXLOS_ATTR_ID(36), + TRANSCEIVER_RXLOS_ATTR_ID(37), + TRANSCEIVER_RXLOS_ATTR_ID(38), + TRANSCEIVER_RXLOS_ATTR_ID(39), + TRANSCEIVER_RXLOS_ATTR_ID(40), + TRANSCEIVER_RXLOS_ATTR_ID(41), + TRANSCEIVER_RXLOS_ATTR_ID(42), + TRANSCEIVER_RXLOS_ATTR_ID(43), + TRANSCEIVER_RXLOS_ATTR_ID(44), + TRANSCEIVER_RXLOS_ATTR_ID(45), + TRANSCEIVER_RXLOS_ATTR_ID(46), + TRANSCEIVER_RXLOS_ATTR_ID(47), + TRANSCEIVER_RXLOS_ATTR_ID(48), + TRANSCEIVER_TXFAULT_ATTR_ID(1), + TRANSCEIVER_TXFAULT_ATTR_ID(2), + TRANSCEIVER_TXFAULT_ATTR_ID(3), + TRANSCEIVER_TXFAULT_ATTR_ID(4), + TRANSCEIVER_TXFAULT_ATTR_ID(5), + TRANSCEIVER_TXFAULT_ATTR_ID(6), + TRANSCEIVER_TXFAULT_ATTR_ID(7), + TRANSCEIVER_TXFAULT_ATTR_ID(8), + TRANSCEIVER_TXFAULT_ATTR_ID(9), + TRANSCEIVER_TXFAULT_ATTR_ID(10), + TRANSCEIVER_TXFAULT_ATTR_ID(11), + TRANSCEIVER_TXFAULT_ATTR_ID(12), + TRANSCEIVER_TXFAULT_ATTR_ID(13), + TRANSCEIVER_TXFAULT_ATTR_ID(14), + TRANSCEIVER_TXFAULT_ATTR_ID(15), + TRANSCEIVER_TXFAULT_ATTR_ID(16), + TRANSCEIVER_TXFAULT_ATTR_ID(17), + TRANSCEIVER_TXFAULT_ATTR_ID(18), + TRANSCEIVER_TXFAULT_ATTR_ID(19), + TRANSCEIVER_TXFAULT_ATTR_ID(20), + TRANSCEIVER_TXFAULT_ATTR_ID(21), + TRANSCEIVER_TXFAULT_ATTR_ID(22), + TRANSCEIVER_TXFAULT_ATTR_ID(23), + TRANSCEIVER_TXFAULT_ATTR_ID(24), + TRANSCEIVER_TXFAULT_ATTR_ID(25), + TRANSCEIVER_TXFAULT_ATTR_ID(26), + TRANSCEIVER_TXFAULT_ATTR_ID(27), + TRANSCEIVER_TXFAULT_ATTR_ID(28), + TRANSCEIVER_TXFAULT_ATTR_ID(29), + TRANSCEIVER_TXFAULT_ATTR_ID(30), + TRANSCEIVER_TXFAULT_ATTR_ID(31), + TRANSCEIVER_TXFAULT_ATTR_ID(32), + TRANSCEIVER_TXFAULT_ATTR_ID(33), + TRANSCEIVER_TXFAULT_ATTR_ID(34), + TRANSCEIVER_TXFAULT_ATTR_ID(35), + TRANSCEIVER_TXFAULT_ATTR_ID(36), + TRANSCEIVER_TXFAULT_ATTR_ID(37), + TRANSCEIVER_TXFAULT_ATTR_ID(38), + TRANSCEIVER_TXFAULT_ATTR_ID(39), + TRANSCEIVER_TXFAULT_ATTR_ID(40), + TRANSCEIVER_TXFAULT_ATTR_ID(41), + TRANSCEIVER_TXFAULT_ATTR_ID(42), + TRANSCEIVER_TXFAULT_ATTR_ID(43), + TRANSCEIVER_TXFAULT_ATTR_ID(44), + TRANSCEIVER_TXFAULT_ATTR_ID(45), + TRANSCEIVER_TXFAULT_ATTR_ID(46), + TRANSCEIVER_TXFAULT_ATTR_ID(47), + TRANSCEIVER_TXFAULT_ATTR_ID(48), }; /* sysfs attributes for hwmon @@ -352,13 +319,9 @@ static ssize_t show_present_all(struct device *dev, struct device_attribute *da, static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, char *buf); static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); -static ssize_t set_lp_mode(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); -static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); + const char *buf, size_t count); static ssize_t access(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); + const char *buf, size_t count); static ssize_t show_version(struct device *dev, struct device_attribute *da, char *buf); static int as5712_54x_cpld_read_internal(struct i2c_client *client, u8 reg); @@ -366,27 +329,17 @@ static int as5712_54x_cpld_write_internal(struct i2c_client *client, u8 reg, u8 /* transceiver attributes */ #define DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(index) \ - static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_status, NULL, MODULE_PRESENT_##index) + static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_status, NULL, MODULE_PRESENT_##index) #define DECLARE_TRANSCEIVER_PRESENT_ATTR(index) &sensor_dev_attr_module_present_##index.dev_attr.attr #define DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ - static SENSOR_DEVICE_ATTR(module_tx_disable_##index, S_IRUGO | S_IWUSR, show_status, set_tx_disable, MODULE_TXDISABLE_##index); \ - static SENSOR_DEVICE_ATTR(module_rx_los_##index, S_IRUGO, show_status, NULL, MODULE_RXLOS_##index); \ - static SENSOR_DEVICE_ATTR(module_tx_fault_##index, S_IRUGO, show_status, NULL, MODULE_TXFAULT_##index) - + static SENSOR_DEVICE_ATTR(module_tx_disable_##index, S_IRUGO | S_IWUSR, show_status, set_tx_disable, MODULE_TXDISABLE_##index); \ + static SENSOR_DEVICE_ATTR(module_rx_los_##index, S_IRUGO, show_status, NULL, MODULE_RXLOS_##index); \ + static SENSOR_DEVICE_ATTR(module_tx_fault_##index, S_IRUGO, show_status, NULL, MODULE_TXFAULT_##index) #define DECLARE_SFP_TRANSCEIVER_ATTR(index) \ - &sensor_dev_attr_module_tx_disable_##index.dev_attr.attr, \ - &sensor_dev_attr_module_rx_los_##index.dev_attr.attr, \ - &sensor_dev_attr_module_tx_fault_##index.dev_attr.attr - -#define DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ - static SENSOR_DEVICE_ATTR(module_lp_mode_##index, S_IRUGO | S_IWUSR, show_status, set_lp_mode, MODULE_LPMODE_##index); \ - static SENSOR_DEVICE_ATTR(module_reset_##index, S_IWUSR | S_IRUGO, show_status, set_mode_reset, MODULE_RESET_##index) - -#define DECLARE_QSFP_TRANSCEIVER_ATTR(index) \ - &sensor_dev_attr_module_lp_mode_##index.dev_attr.attr, \ - &sensor_dev_attr_module_reset_##index.dev_attr.attr - + &sensor_dev_attr_module_tx_disable_##index.dev_attr.attr, \ + &sensor_dev_attr_module_rx_los_##index.dev_attr.attr, \ + &sensor_dev_attr_module_tx_fault_##index.dev_attr.attr static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION); static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS); @@ -496,167 +449,156 @@ DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(45); DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(46); DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(47); DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(48); -DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(49); -DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(50); -DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(51); -DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(52); -DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(53); -DECLARE_QSFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(54); static struct attribute *as5712_54x_cpld1_attributes[] = { &sensor_dev_attr_version.dev_attr.attr, &sensor_dev_attr_access.dev_attr.attr, - NULL + NULL }; static const struct attribute_group as5712_54x_cpld1_group = { - .attrs = as5712_54x_cpld1_attributes, + .attrs = as5712_54x_cpld1_attributes, }; static struct attribute *as5712_54x_cpld2_attributes[] = { &sensor_dev_attr_version.dev_attr.attr, &sensor_dev_attr_access.dev_attr.attr, - /* transceiver attributes */ - &sensor_dev_attr_module_present_all.dev_attr.attr, - &sensor_dev_attr_module_rx_los_all.dev_attr.attr, - DECLARE_TRANSCEIVER_PRESENT_ATTR(1), - DECLARE_TRANSCEIVER_PRESENT_ATTR(2), - DECLARE_TRANSCEIVER_PRESENT_ATTR(3), - DECLARE_TRANSCEIVER_PRESENT_ATTR(4), - DECLARE_TRANSCEIVER_PRESENT_ATTR(5), - DECLARE_TRANSCEIVER_PRESENT_ATTR(6), - DECLARE_TRANSCEIVER_PRESENT_ATTR(7), - DECLARE_TRANSCEIVER_PRESENT_ATTR(8), - DECLARE_TRANSCEIVER_PRESENT_ATTR(9), - DECLARE_TRANSCEIVER_PRESENT_ATTR(10), - DECLARE_TRANSCEIVER_PRESENT_ATTR(11), - DECLARE_TRANSCEIVER_PRESENT_ATTR(12), - DECLARE_TRANSCEIVER_PRESENT_ATTR(13), - DECLARE_TRANSCEIVER_PRESENT_ATTR(14), - DECLARE_TRANSCEIVER_PRESENT_ATTR(15), - DECLARE_TRANSCEIVER_PRESENT_ATTR(16), - DECLARE_TRANSCEIVER_PRESENT_ATTR(17), - DECLARE_TRANSCEIVER_PRESENT_ATTR(18), - DECLARE_TRANSCEIVER_PRESENT_ATTR(19), - DECLARE_TRANSCEIVER_PRESENT_ATTR(20), - DECLARE_TRANSCEIVER_PRESENT_ATTR(21), - DECLARE_TRANSCEIVER_PRESENT_ATTR(22), - DECLARE_TRANSCEIVER_PRESENT_ATTR(23), - DECLARE_TRANSCEIVER_PRESENT_ATTR(24), - DECLARE_SFP_TRANSCEIVER_ATTR(1), - DECLARE_SFP_TRANSCEIVER_ATTR(2), - DECLARE_SFP_TRANSCEIVER_ATTR(3), - DECLARE_SFP_TRANSCEIVER_ATTR(4), - DECLARE_SFP_TRANSCEIVER_ATTR(5), - DECLARE_SFP_TRANSCEIVER_ATTR(6), - DECLARE_SFP_TRANSCEIVER_ATTR(7), - DECLARE_SFP_TRANSCEIVER_ATTR(8), - DECLARE_SFP_TRANSCEIVER_ATTR(9), - DECLARE_SFP_TRANSCEIVER_ATTR(10), - DECLARE_SFP_TRANSCEIVER_ATTR(11), - DECLARE_SFP_TRANSCEIVER_ATTR(12), - DECLARE_SFP_TRANSCEIVER_ATTR(13), - DECLARE_SFP_TRANSCEIVER_ATTR(14), - DECLARE_SFP_TRANSCEIVER_ATTR(15), - DECLARE_SFP_TRANSCEIVER_ATTR(16), - DECLARE_SFP_TRANSCEIVER_ATTR(17), - DECLARE_SFP_TRANSCEIVER_ATTR(18), - DECLARE_SFP_TRANSCEIVER_ATTR(19), - DECLARE_SFP_TRANSCEIVER_ATTR(20), - DECLARE_SFP_TRANSCEIVER_ATTR(21), - DECLARE_SFP_TRANSCEIVER_ATTR(22), - DECLARE_SFP_TRANSCEIVER_ATTR(23), - DECLARE_SFP_TRANSCEIVER_ATTR(24), - NULL + /* transceiver attributes */ + &sensor_dev_attr_module_present_all.dev_attr.attr, + &sensor_dev_attr_module_rx_los_all.dev_attr.attr, + DECLARE_TRANSCEIVER_PRESENT_ATTR(1), + DECLARE_TRANSCEIVER_PRESENT_ATTR(2), + DECLARE_TRANSCEIVER_PRESENT_ATTR(3), + DECLARE_TRANSCEIVER_PRESENT_ATTR(4), + DECLARE_TRANSCEIVER_PRESENT_ATTR(5), + DECLARE_TRANSCEIVER_PRESENT_ATTR(6), + DECLARE_TRANSCEIVER_PRESENT_ATTR(7), + DECLARE_TRANSCEIVER_PRESENT_ATTR(8), + DECLARE_TRANSCEIVER_PRESENT_ATTR(9), + DECLARE_TRANSCEIVER_PRESENT_ATTR(10), + DECLARE_TRANSCEIVER_PRESENT_ATTR(11), + DECLARE_TRANSCEIVER_PRESENT_ATTR(12), + DECLARE_TRANSCEIVER_PRESENT_ATTR(13), + DECLARE_TRANSCEIVER_PRESENT_ATTR(14), + DECLARE_TRANSCEIVER_PRESENT_ATTR(15), + DECLARE_TRANSCEIVER_PRESENT_ATTR(16), + DECLARE_TRANSCEIVER_PRESENT_ATTR(17), + DECLARE_TRANSCEIVER_PRESENT_ATTR(18), + DECLARE_TRANSCEIVER_PRESENT_ATTR(19), + DECLARE_TRANSCEIVER_PRESENT_ATTR(20), + DECLARE_TRANSCEIVER_PRESENT_ATTR(21), + DECLARE_TRANSCEIVER_PRESENT_ATTR(22), + DECLARE_TRANSCEIVER_PRESENT_ATTR(23), + DECLARE_TRANSCEIVER_PRESENT_ATTR(24), + DECLARE_SFP_TRANSCEIVER_ATTR(1), + DECLARE_SFP_TRANSCEIVER_ATTR(2), + DECLARE_SFP_TRANSCEIVER_ATTR(3), + DECLARE_SFP_TRANSCEIVER_ATTR(4), + DECLARE_SFP_TRANSCEIVER_ATTR(5), + DECLARE_SFP_TRANSCEIVER_ATTR(6), + DECLARE_SFP_TRANSCEIVER_ATTR(7), + DECLARE_SFP_TRANSCEIVER_ATTR(8), + DECLARE_SFP_TRANSCEIVER_ATTR(9), + DECLARE_SFP_TRANSCEIVER_ATTR(10), + DECLARE_SFP_TRANSCEIVER_ATTR(11), + DECLARE_SFP_TRANSCEIVER_ATTR(12), + DECLARE_SFP_TRANSCEIVER_ATTR(13), + DECLARE_SFP_TRANSCEIVER_ATTR(14), + DECLARE_SFP_TRANSCEIVER_ATTR(15), + DECLARE_SFP_TRANSCEIVER_ATTR(16), + DECLARE_SFP_TRANSCEIVER_ATTR(17), + DECLARE_SFP_TRANSCEIVER_ATTR(18), + DECLARE_SFP_TRANSCEIVER_ATTR(19), + DECLARE_SFP_TRANSCEIVER_ATTR(20), + DECLARE_SFP_TRANSCEIVER_ATTR(21), + DECLARE_SFP_TRANSCEIVER_ATTR(22), + DECLARE_SFP_TRANSCEIVER_ATTR(23), + DECLARE_SFP_TRANSCEIVER_ATTR(24), + NULL }; static const struct attribute_group as5712_54x_cpld2_group = { - .attrs = as5712_54x_cpld2_attributes, + .attrs = as5712_54x_cpld2_attributes, }; static struct attribute *as5712_54x_cpld3_attributes[] = { &sensor_dev_attr_version.dev_attr.attr, &sensor_dev_attr_access.dev_attr.attr, - /* transceiver attributes */ - &sensor_dev_attr_module_present_all.dev_attr.attr, - &sensor_dev_attr_module_rx_los_all.dev_attr.attr, - DECLARE_TRANSCEIVER_PRESENT_ATTR(25), - DECLARE_TRANSCEIVER_PRESENT_ATTR(26), - DECLARE_TRANSCEIVER_PRESENT_ATTR(27), - DECLARE_TRANSCEIVER_PRESENT_ATTR(28), - DECLARE_TRANSCEIVER_PRESENT_ATTR(29), - DECLARE_TRANSCEIVER_PRESENT_ATTR(30), - DECLARE_TRANSCEIVER_PRESENT_ATTR(31), - DECLARE_TRANSCEIVER_PRESENT_ATTR(32), - DECLARE_TRANSCEIVER_PRESENT_ATTR(33), - DECLARE_TRANSCEIVER_PRESENT_ATTR(34), - DECLARE_TRANSCEIVER_PRESENT_ATTR(35), - DECLARE_TRANSCEIVER_PRESENT_ATTR(36), - DECLARE_TRANSCEIVER_PRESENT_ATTR(37), - DECLARE_TRANSCEIVER_PRESENT_ATTR(38), - DECLARE_TRANSCEIVER_PRESENT_ATTR(39), - DECLARE_TRANSCEIVER_PRESENT_ATTR(40), - DECLARE_TRANSCEIVER_PRESENT_ATTR(41), - DECLARE_TRANSCEIVER_PRESENT_ATTR(42), - DECLARE_TRANSCEIVER_PRESENT_ATTR(43), - DECLARE_TRANSCEIVER_PRESENT_ATTR(44), - DECLARE_TRANSCEIVER_PRESENT_ATTR(45), - DECLARE_TRANSCEIVER_PRESENT_ATTR(46), - DECLARE_TRANSCEIVER_PRESENT_ATTR(47), - DECLARE_TRANSCEIVER_PRESENT_ATTR(48), - DECLARE_TRANSCEIVER_PRESENT_ATTR(49), - DECLARE_TRANSCEIVER_PRESENT_ATTR(50), - DECLARE_TRANSCEIVER_PRESENT_ATTR(51), - DECLARE_TRANSCEIVER_PRESENT_ATTR(52), - DECLARE_TRANSCEIVER_PRESENT_ATTR(53), - DECLARE_TRANSCEIVER_PRESENT_ATTR(54), - DECLARE_SFP_TRANSCEIVER_ATTR(25), - DECLARE_SFP_TRANSCEIVER_ATTR(26), - DECLARE_SFP_TRANSCEIVER_ATTR(27), - DECLARE_SFP_TRANSCEIVER_ATTR(28), - DECLARE_SFP_TRANSCEIVER_ATTR(29), - DECLARE_SFP_TRANSCEIVER_ATTR(30), - DECLARE_SFP_TRANSCEIVER_ATTR(31), - DECLARE_SFP_TRANSCEIVER_ATTR(32), - DECLARE_SFP_TRANSCEIVER_ATTR(33), - DECLARE_SFP_TRANSCEIVER_ATTR(34), - DECLARE_SFP_TRANSCEIVER_ATTR(35), - DECLARE_SFP_TRANSCEIVER_ATTR(36), - DECLARE_SFP_TRANSCEIVER_ATTR(37), - DECLARE_SFP_TRANSCEIVER_ATTR(38), - DECLARE_SFP_TRANSCEIVER_ATTR(39), - DECLARE_SFP_TRANSCEIVER_ATTR(40), - DECLARE_SFP_TRANSCEIVER_ATTR(41), - DECLARE_SFP_TRANSCEIVER_ATTR(42), - DECLARE_SFP_TRANSCEIVER_ATTR(43), - DECLARE_SFP_TRANSCEIVER_ATTR(44), - DECLARE_SFP_TRANSCEIVER_ATTR(45), - DECLARE_SFP_TRANSCEIVER_ATTR(46), - DECLARE_SFP_TRANSCEIVER_ATTR(47), - DECLARE_SFP_TRANSCEIVER_ATTR(48), - DECLARE_QSFP_TRANSCEIVER_ATTR(49), - DECLARE_QSFP_TRANSCEIVER_ATTR(50), - DECLARE_QSFP_TRANSCEIVER_ATTR(51), - DECLARE_QSFP_TRANSCEIVER_ATTR(52), - DECLARE_QSFP_TRANSCEIVER_ATTR(53), - DECLARE_QSFP_TRANSCEIVER_ATTR(54), - NULL + /* transceiver attributes */ + &sensor_dev_attr_module_present_all.dev_attr.attr, + &sensor_dev_attr_module_rx_los_all.dev_attr.attr, + DECLARE_TRANSCEIVER_PRESENT_ATTR(25), + DECLARE_TRANSCEIVER_PRESENT_ATTR(26), + DECLARE_TRANSCEIVER_PRESENT_ATTR(27), + DECLARE_TRANSCEIVER_PRESENT_ATTR(28), + DECLARE_TRANSCEIVER_PRESENT_ATTR(29), + DECLARE_TRANSCEIVER_PRESENT_ATTR(30), + DECLARE_TRANSCEIVER_PRESENT_ATTR(31), + DECLARE_TRANSCEIVER_PRESENT_ATTR(32), + DECLARE_TRANSCEIVER_PRESENT_ATTR(33), + DECLARE_TRANSCEIVER_PRESENT_ATTR(34), + DECLARE_TRANSCEIVER_PRESENT_ATTR(35), + DECLARE_TRANSCEIVER_PRESENT_ATTR(36), + DECLARE_TRANSCEIVER_PRESENT_ATTR(37), + DECLARE_TRANSCEIVER_PRESENT_ATTR(38), + DECLARE_TRANSCEIVER_PRESENT_ATTR(39), + DECLARE_TRANSCEIVER_PRESENT_ATTR(40), + DECLARE_TRANSCEIVER_PRESENT_ATTR(41), + DECLARE_TRANSCEIVER_PRESENT_ATTR(42), + DECLARE_TRANSCEIVER_PRESENT_ATTR(43), + DECLARE_TRANSCEIVER_PRESENT_ATTR(44), + DECLARE_TRANSCEIVER_PRESENT_ATTR(45), + DECLARE_TRANSCEIVER_PRESENT_ATTR(46), + DECLARE_TRANSCEIVER_PRESENT_ATTR(47), + DECLARE_TRANSCEIVER_PRESENT_ATTR(48), + DECLARE_TRANSCEIVER_PRESENT_ATTR(49), + DECLARE_TRANSCEIVER_PRESENT_ATTR(50), + DECLARE_TRANSCEIVER_PRESENT_ATTR(51), + DECLARE_TRANSCEIVER_PRESENT_ATTR(52), + DECLARE_TRANSCEIVER_PRESENT_ATTR(53), + DECLARE_TRANSCEIVER_PRESENT_ATTR(54), + DECLARE_SFP_TRANSCEIVER_ATTR(25), + DECLARE_SFP_TRANSCEIVER_ATTR(26), + DECLARE_SFP_TRANSCEIVER_ATTR(27), + DECLARE_SFP_TRANSCEIVER_ATTR(28), + DECLARE_SFP_TRANSCEIVER_ATTR(29), + DECLARE_SFP_TRANSCEIVER_ATTR(30), + DECLARE_SFP_TRANSCEIVER_ATTR(31), + DECLARE_SFP_TRANSCEIVER_ATTR(32), + DECLARE_SFP_TRANSCEIVER_ATTR(33), + DECLARE_SFP_TRANSCEIVER_ATTR(34), + DECLARE_SFP_TRANSCEIVER_ATTR(35), + DECLARE_SFP_TRANSCEIVER_ATTR(36), + DECLARE_SFP_TRANSCEIVER_ATTR(37), + DECLARE_SFP_TRANSCEIVER_ATTR(38), + DECLARE_SFP_TRANSCEIVER_ATTR(39), + DECLARE_SFP_TRANSCEIVER_ATTR(40), + DECLARE_SFP_TRANSCEIVER_ATTR(41), + DECLARE_SFP_TRANSCEIVER_ATTR(42), + DECLARE_SFP_TRANSCEIVER_ATTR(43), + DECLARE_SFP_TRANSCEIVER_ATTR(44), + DECLARE_SFP_TRANSCEIVER_ATTR(45), + DECLARE_SFP_TRANSCEIVER_ATTR(46), + DECLARE_SFP_TRANSCEIVER_ATTR(47), + DECLARE_SFP_TRANSCEIVER_ATTR(48), + NULL }; static const struct attribute_group as5712_54x_cpld3_group = { - .attrs = as5712_54x_cpld3_attributes, + .attrs = as5712_54x_cpld3_attributes, }; static ssize_t show_present_all(struct device *dev, struct device_attribute *da, char *buf) { - int i, status, num_regs = 0; - u8 values[4] = {0}; - u8 regs[] = {0x6, 0x7, 0x8, 0x14}; - struct i2c_client *client = to_i2c_client(dev); - struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); + int i, status, num_regs = 0; + u8 values[4] = {0}; + u8 regs[] = {0x6, 0x7, 0x8, 0x14}; + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc); - mutex_lock(&data->update_lock); + mutex_lock(&data->update_lock); num_regs = (data->type == as5712_54x_cpld2) ? 3 : 4; @@ -670,7 +612,7 @@ static ssize_t show_present_all(struct device *dev, struct device_attribute *da, values[i] = ~(u8)status; } - mutex_unlock(&data->update_lock); + mutex_unlock(&data->update_lock); /* Return values 1 -> 54 in order */ if (data->type == as5712_54x_cpld2) { @@ -686,20 +628,21 @@ static ssize_t show_present_all(struct device *dev, struct device_attribute *da, return status; exit: - mutex_unlock(&data->update_lock); - return status; + mutex_unlock(&data->update_lock); + return status; } static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, char *buf) { - int i, status; - u8 values[3] = {0}; - u8 regs[] = {0xF, 0x10, 0x11}; - struct i2c_client *client = to_i2c_client(dev); - struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); + int i, status; + u8 values[3] = {0}; + u8 regs[] = {0xF, 0x10, 0x11}; + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc); - mutex_lock(&data->update_lock); + mutex_lock(&data->update_lock); for (i = 0; i < ARRAY_SIZE(regs); i++) { status = as5712_54x_cpld_read_internal(client, regs[i]); @@ -711,14 +654,14 @@ static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, values[i] = (u8)status; } - mutex_unlock(&data->update_lock); + mutex_unlock(&data->update_lock); /* Return values 1 -> 24 in order */ return sprintf(buf, "%.2x %.2x %.2x\n", values[0], values[1], values[2]); exit: - mutex_unlock(&data->update_lock); - return status; + mutex_unlock(&data->update_lock); + return status; } static ssize_t show_status(struct device *dev, struct device_attribute *da, @@ -726,35 +669,36 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct i2c_client *client = to_i2c_client(dev); - struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); - int status = 0; - u8 reg = 0, mask = 0, revert = 0; - - switch (attr->index) { - case MODULE_PRESENT_1 ... MODULE_PRESENT_8: - reg = 0x6; - mask = 0x1 << (attr->index - MODULE_PRESENT_1); - break; - case MODULE_PRESENT_9 ... MODULE_PRESENT_16: - reg = 0x7; - mask = 0x1 << (attr->index - MODULE_PRESENT_9); - break; - case MODULE_PRESENT_17 ... MODULE_PRESENT_24: - reg = 0x8; - mask = 0x1 << (attr->index - MODULE_PRESENT_17); - break; - case MODULE_PRESENT_25 ... MODULE_PRESENT_32: - reg = 0x6; - mask = 0x1 << (attr->index - MODULE_PRESENT_25); - break; - case MODULE_PRESENT_33 ... MODULE_PRESENT_40: - reg = 0x7; - mask = 0x1 << (attr->index - MODULE_PRESENT_33); - break; - case MODULE_PRESENT_41 ... MODULE_PRESENT_48: - reg = 0x8; - mask = 0x1 << (attr->index - MODULE_PRESENT_41); - break; + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc); + int status = 0; + u8 reg = 0, mask = 0, revert = 0; + + switch (attr->index) { + case MODULE_PRESENT_1 ... MODULE_PRESENT_8: + reg = 0x6; + mask = 0x1 << (attr->index - MODULE_PRESENT_1); + break; + case MODULE_PRESENT_9 ... MODULE_PRESENT_16: + reg = 0x7; + mask = 0x1 << (attr->index - MODULE_PRESENT_9); + break; + case MODULE_PRESENT_17 ... MODULE_PRESENT_24: + reg = 0x8; + mask = 0x1 << (attr->index - MODULE_PRESENT_17); + break; + case MODULE_PRESENT_25 ... MODULE_PRESENT_32: + reg = 0x6; + mask = 0x1 << (attr->index - MODULE_PRESENT_25); + break; + case MODULE_PRESENT_33 ... MODULE_PRESENT_40: + reg = 0x7; + mask = 0x1 << (attr->index - MODULE_PRESENT_33); + break; + case MODULE_PRESENT_41 ... MODULE_PRESENT_48: + reg = 0x8; + mask = 0x1 << (attr->index - MODULE_PRESENT_41); + break; case MODULE_PRESENT_49: reg = 0x14; mask = 0x1; @@ -779,247 +723,145 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da, reg = 0x14; mask = 0x20; break; - case MODULE_TXFAULT_1 ... MODULE_TXFAULT_8: - reg = 0x9; - mask = 0x1 << (attr->index - MODULE_TXFAULT_1); - break; - case MODULE_TXFAULT_9 ... MODULE_TXFAULT_16: - reg = 0xA; - mask = 0x1 << (attr->index - MODULE_TXFAULT_9); - break; - case MODULE_TXFAULT_17 ... MODULE_TXFAULT_24: - reg = 0xB; - mask = 0x1 << (attr->index - MODULE_TXFAULT_17); - break; - case MODULE_TXFAULT_25 ... MODULE_TXFAULT_32: - reg = 0x9; - mask = 0x1 << (attr->index - MODULE_TXFAULT_25); - break; - case MODULE_TXFAULT_33 ... MODULE_TXFAULT_40: - reg = 0xA; - mask = 0x1 << (attr->index - MODULE_TXFAULT_33); - break; - case MODULE_TXFAULT_41 ... MODULE_TXFAULT_48: - reg = 0xB; - mask = 0x1 << (attr->index - MODULE_TXFAULT_41); - break; - case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_8: - reg = 0xC; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_1); - break; - case MODULE_TXDISABLE_9 ... MODULE_TXDISABLE_16: - reg = 0xD; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_9); - break; - case MODULE_TXDISABLE_17 ... MODULE_TXDISABLE_24: - reg = 0xE; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_17); - break; - case MODULE_TXDISABLE_25 ... MODULE_TXDISABLE_32: - reg = 0xC; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_25); - break; - case MODULE_TXDISABLE_33 ... MODULE_TXDISABLE_40: - reg = 0xD; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_33); - break; - case MODULE_TXDISABLE_41 ... MODULE_TXDISABLE_48: - reg = 0xE; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_41); - break; - case MODULE_RXLOS_1 ... MODULE_RXLOS_8: - reg = 0xF; - mask = 0x1 << (attr->index - MODULE_RXLOS_1); - break; - case MODULE_RXLOS_9 ... MODULE_RXLOS_16: - reg = 0x10; - mask = 0x1 << (attr->index - MODULE_RXLOS_9); - break; - case MODULE_RXLOS_17 ... MODULE_RXLOS_24: - reg = 0x11; - mask = 0x1 << (attr->index - MODULE_RXLOS_17); - break; - case MODULE_RXLOS_25 ... MODULE_RXLOS_32: - reg = 0xF; - mask = 0x1 << (attr->index - MODULE_RXLOS_25); - break; - case MODULE_RXLOS_33 ... MODULE_RXLOS_40: - reg = 0x10; - mask = 0x1 << (attr->index - MODULE_RXLOS_33); - break; - case MODULE_RXLOS_41 ... MODULE_RXLOS_48: - reg = 0x11; - mask = 0x1 << (attr->index - MODULE_RXLOS_41); - break; - case MODULE_LPMODE_49 ... MODULE_LPMODE_54: - reg = 0x16; - mask = 0x1 << (attr->index - MODULE_LPMODE_49); + case MODULE_TXFAULT_1 ... MODULE_TXFAULT_8: + reg = 0x9; + mask = 0x1 << (attr->index - MODULE_TXFAULT_1); + break; + case MODULE_TXFAULT_9 ... MODULE_TXFAULT_16: + reg = 0xA; + mask = 0x1 << (attr->index - MODULE_TXFAULT_9); + break; + case MODULE_TXFAULT_17 ... MODULE_TXFAULT_24: + reg = 0xB; + mask = 0x1 << (attr->index - MODULE_TXFAULT_17); + break; + case MODULE_TXFAULT_25 ... MODULE_TXFAULT_32: + reg = 0x9; + mask = 0x1 << (attr->index - MODULE_TXFAULT_25); + break; + case MODULE_TXFAULT_33 ... MODULE_TXFAULT_40: + reg = 0xA; + mask = 0x1 << (attr->index - MODULE_TXFAULT_33); + break; + case MODULE_TXFAULT_41 ... MODULE_TXFAULT_48: + reg = 0xB; + mask = 0x1 << (attr->index - MODULE_TXFAULT_41); + break; + case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_8: + reg = 0xC; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_1); + break; + case MODULE_TXDISABLE_9 ... MODULE_TXDISABLE_16: + reg = 0xD; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_9); + break; + case MODULE_TXDISABLE_17 ... MODULE_TXDISABLE_24: + reg = 0xE; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_17); + break; + case MODULE_TXDISABLE_25 ... MODULE_TXDISABLE_32: + reg = 0xC; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_25); + break; + case MODULE_TXDISABLE_33 ... MODULE_TXDISABLE_40: + reg = 0xD; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_33); break; - case MODULE_RESET_49 ... MODULE_RESET_54: - reg = 0x15; - mask = 0x1 << (attr->index - MODULE_RESET_49); + case MODULE_TXDISABLE_41 ... MODULE_TXDISABLE_48: + reg = 0xE; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_41); break; - default: - return 0; - } + case MODULE_RXLOS_1 ... MODULE_RXLOS_8: + reg = 0xF; + mask = 0x1 << (attr->index - MODULE_RXLOS_1); + break; + case MODULE_RXLOS_9 ... MODULE_RXLOS_16: + reg = 0x10; + mask = 0x1 << (attr->index - MODULE_RXLOS_9); + break; + case MODULE_RXLOS_17 ... MODULE_RXLOS_24: + reg = 0x11; + mask = 0x1 << (attr->index - MODULE_RXLOS_17); + break; + case MODULE_RXLOS_25 ... MODULE_RXLOS_32: + reg = 0xF; + mask = 0x1 << (attr->index - MODULE_RXLOS_25); + break; + case MODULE_RXLOS_33 ... MODULE_RXLOS_40: + reg = 0x10; + mask = 0x1 << (attr->index - MODULE_RXLOS_33); + break; + case MODULE_RXLOS_41 ... MODULE_RXLOS_48: + reg = 0x11; + mask = 0x1 << (attr->index - MODULE_RXLOS_41); + break; + default: + return 0; + } if (attr->index >= MODULE_PRESENT_1 && attr->index <= MODULE_PRESENT_54) { revert = 1; } mutex_lock(&data->update_lock); - status = as5712_54x_cpld_read_internal(client, reg); - if (unlikely(status < 0)) { - goto exit; - } - mutex_unlock(&data->update_lock); - - return sprintf(buf, "%d\n", revert ? !(status & mask) : !!(status & mask)); - -exit: - mutex_unlock(&data->update_lock); - return status; -} - -static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); - long disable; - int status; - u8 reg = 0, mask = 0; - - status = kstrtol(buf, 10, &disable); - if (status) { - return status; - } - - switch (attr->index) { - case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_8: - reg = 0xC; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_1); - break; - case MODULE_TXDISABLE_9 ... MODULE_TXDISABLE_16: - reg = 0xD; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_9); - break; - case MODULE_TXDISABLE_17 ... MODULE_TXDISABLE_24: - reg = 0xE; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_17); - break; - case MODULE_TXDISABLE_25 ... MODULE_TXDISABLE_32: - reg = 0xC; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_25); - break; - case MODULE_TXDISABLE_33 ... MODULE_TXDISABLE_40: - reg = 0xD; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_33); - break; - case MODULE_TXDISABLE_41 ... MODULE_TXDISABLE_48: - reg = 0xE; - mask = 0x1 << (attr->index - MODULE_TXDISABLE_41); - break; - default: - return 0; - } - - /* Read current status */ - mutex_lock(&data->update_lock); - status = as5712_54x_cpld_read_internal(client, reg); - if (unlikely(status < 0)) { - goto exit; - } - - /* Update tx_disable status */ - if (disable) { - status |= mask; - } - else { - status &= ~mask; - } - - status = as5712_54x_cpld_write_internal(client, reg, status); - if (unlikely(status < 0)) { - goto exit; - } - - mutex_unlock(&data->update_lock); - return count; - -exit: - mutex_unlock(&data->update_lock); - return status; -} - -static ssize_t set_lp_mode(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); - long on; - int status= -ENOENT; - u8 reg = 0x16, mask = 0; - - if(attr->index < MODULE_LPMODE_49 || attr->index > MODULE_LPMODE_54) - return status; - - status = kstrtol(buf, 10, &on); - if (status) { - return status; - } - - /* Read current status */ - mutex_lock(&data->update_lock); - status = as5712_54x_cpld_read_internal(client, reg); - if (unlikely(status < 0)) { - goto exit; - } - - mask = 0x1 << (attr->index - MODULE_LPMODE_49); - - /* Update lp_mode status */ - if (on) { - status |= mask; - } - else { - status &= ~mask; - } - - status = as5712_54x_cpld_write_internal(client, reg, status); + status = as5712_54x_cpld_read_internal(client, reg); if (unlikely(status < 0)) { goto exit; } - mutex_unlock(&data->update_lock); - return count; + + return sprintf(buf, "%d\n", revert ? !(status & mask) : !!(status & mask)); exit: mutex_unlock(&data->update_lock); return status; - } -static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) +static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); - long on; - int status= -ENOENT; - u8 reg = 0x15, mask = 0; - - if(attr->index < MODULE_RESET_49 || attr->index > MODULE_RESET_54) - return status; + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc); + long disable; + int status; + u8 reg = 0, mask = 0; - status = kstrtol(buf, 10, &on); + status = kstrtol(buf, 10, &disable); if (status) { return status; } + switch (attr->index) { + case MODULE_TXDISABLE_1 ... MODULE_TXDISABLE_8: + reg = 0xC; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_1); + break; + case MODULE_TXDISABLE_9 ... MODULE_TXDISABLE_16: + reg = 0xD; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_9); + break; + case MODULE_TXDISABLE_17 ... MODULE_TXDISABLE_24: + reg = 0xE; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_17); + break; + case MODULE_TXDISABLE_25 ... MODULE_TXDISABLE_32: + reg = 0xC; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_25); + break; + case MODULE_TXDISABLE_33 ... MODULE_TXDISABLE_40: + reg = 0xD; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_33); + break; + case MODULE_TXDISABLE_41 ... MODULE_TXDISABLE_48: + reg = 0xE; + mask = 0x1 << (attr->index - MODULE_TXDISABLE_41); + break; + default: + return 0; + } + /* Read current status */ mutex_lock(&data->update_lock); status = as5712_54x_cpld_read_internal(client, reg); @@ -1027,63 +869,61 @@ static ssize_t set_mode_reset(struct device *dev, struct device_attribute *da, goto exit; } - mask = 0x1 << (attr->index - MODULE_RESET_49); - /* Update tx_disable status */ - if (on) { - status |= mask; + if (disable) { + status |= mask; } else { - status &= ~mask; + status &= ~mask; } status = as5712_54x_cpld_write_internal(client, reg, status); if (unlikely(status < 0)) { goto exit; - } + } mutex_unlock(&data->update_lock); return count; exit: - mutex_unlock(&data->update_lock); - return status; - + mutex_unlock(&data->update_lock); + return status; } static ssize_t access(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) + const char *buf, size_t count) { + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc); int status; u32 addr, val; - struct i2c_client *client = to_i2c_client(dev); - struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); - if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) { - return -EINVAL; - } + if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) { + return -EINVAL; + } - if (addr > 0xFF || val > 0xFF) { - return -EINVAL; - } + if (addr > 0xFF || val > 0xFF) { + return -EINVAL; + } - mutex_lock(&data->update_lock); - status = as5712_54x_cpld_write_internal(client, addr, val); - if (unlikely(status < 0)) { - goto exit; - } - mutex_unlock(&data->update_lock); - return count; + mutex_lock(&data->update_lock); + status = as5712_54x_cpld_write_internal(client, addr, val); + if (unlikely(status < 0)) { + goto exit; + } + mutex_unlock(&data->update_lock); + return count; exit: - mutex_unlock(&data->update_lock); - return status; + mutex_unlock(&data->update_lock); + return status; } /* Write to mux register. Don't use i2c_transfer()/i2c_smbus_xfer() for this as they will try to lock adapter a second time */ static int as5712_54x_cpld_mux_reg_write(struct i2c_adapter *adap, - struct i2c_client *client, u8 val) + struct i2c_client *client, u8 val) { unsigned long orig_jiffies; unsigned short flags; @@ -1099,31 +939,29 @@ static int as5712_54x_cpld_mux_reg_write(struct i2c_adapter *adap, /* Retry automatically on arbitration loss */ orig_jiffies = jiffies; for (res = 0, try = 0; try <= adap->retries; try++) { - res = adap->algo->smbus_xfer(adap, client->addr, flags, - I2C_SMBUS_WRITE, CPLD_CHANNEL_SELECT_REG, - I2C_SMBUS_BYTE_DATA, &data); - if (res != -EAGAIN) - break; - if (time_after(jiffies, - orig_jiffies + adap->timeout)) - break; - } + res = adap->algo->smbus_xfer(adap, client->addr, flags, + I2C_SMBUS_WRITE, CPLD_CHANNEL_SELECT_REG, + I2C_SMBUS_BYTE_DATA, &data); + if (res != -EAGAIN) + break; + if (time_after(jiffies, + orig_jiffies + adap->timeout)) + break; + } } return res; - } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) -static int as5712_54x_cpld_mux_select_chan(struct i2c_mux_core *muxc, - u32 chan) +static int as5712_54x_cpld_mux_select_chan(struct i2c_mux_core *muxc, + u32 chan) { struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc); struct i2c_client *client = data->client; u8 regval; int ret = 0; - regval = chan; + regval = chan; /* Only select the channel if its different from the last channel */ if (data->last_chan != regval) { ret = as5712_54x_cpld_mux_reg_write(muxc->parent, client, regval); @@ -1134,7 +972,7 @@ static int as5712_54x_cpld_mux_select_chan(struct i2c_mux_core *muxc, } static int as5712_54x_cpld_mux_deselect_mux(struct i2c_mux_core *muxc, - u32 chan) + u32 chan) { struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc); struct i2c_client *client = data->client; @@ -1144,37 +982,6 @@ static int as5712_54x_cpld_mux_deselect_mux(struct i2c_mux_core *muxc, return as5712_54x_cpld_mux_reg_write(muxc->parent, client, data->last_chan); } -#else - -static int as5712_54x_cpld_mux_select_chan(struct i2c_adapter *adap, - void *client, u32 chan) -{ - struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); - u8 regval; - int ret = 0; - regval = chan; - - /* Only select the channel if its different from the last channel */ - if (data->last_chan != regval) { - ret = as5712_54x_cpld_mux_reg_write(adap, client, regval); - data->last_chan = regval; - } - - return ret; -} - -static int as5712_54x_cpld_mux_deselect_mux(struct i2c_adapter *adap, - void *client, u32 chan) -{ - struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); - - /* Deselect active channel */ - data->last_chan = chips[data->type].deselectChan; - - return as5712_54x_cpld_mux_reg_write(adap, client, data->last_chan); -} - -#endif /*#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)*/ static void as5712_54x_cpld_add_client(struct i2c_client *client) { @@ -1200,8 +1007,7 @@ static void as5712_54x_cpld_remove_client(struct i2c_client *client) mutex_lock(&list_lock); - list_for_each(list_node, &cpld_client_list) - { + list_for_each(list_node, &cpld_client_list) { cpld_node = list_entry(list_node, struct cpld_client_node, list); if (cpld_node->client == client) { @@ -1222,13 +1028,13 @@ static ssize_t show_version(struct device *dev, struct device_attribute *attr, c { int val = 0; struct i2c_client *client = to_i2c_client(dev); - + val = i2c_smbus_read_byte_data(client, 0x1); if (val < 0) { dev_dbg(&client->dev, "cpld(0x%x) reg(0x1) err %d\n", client->addr, val); -} - + } + return sprintf(buf, "%d", val); } @@ -1236,122 +1042,94 @@ static ssize_t show_version(struct device *dev, struct device_attribute *attr, c * I2C init/probing/exit functions */ static int as5712_54x_cpld_mux_probe(struct i2c_client *client, - const struct i2c_device_id *id) + const struct i2c_device_id *id) { struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); - #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) - int force, class; + int num, force, class; struct i2c_mux_core *muxc; -#endif - - int chan=0; struct as5712_54x_cpld_data *data; - int ret = -ENODEV; + int ret = 0; const struct attribute_group *group = NULL; if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) - goto exit; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) + return -ENODEV; + muxc = i2c_mux_alloc(adap, &client->dev, - chips[id->driver_data].nchans, - sizeof(*data), 0, - accton_i2c_cpld_mux_select_chan, - accton_i2c_cpld_mux_deselect_mux); + chips[id->driver_data].nchans, sizeof(*data), 0, + as5712_54x_cpld_mux_select_chan, as5712_54x_cpld_mux_deselect_mux); if (!muxc) return -ENOMEM; + i2c_set_clientdata(client, muxc); data = i2c_mux_priv(muxc); - i2c_set_clientdata(client, data); - data->muxc = muxc; data->client = client; -#else - - data = kzalloc(sizeof(struct as5712_54x_cpld_data), GFP_KERNEL); - if (!data) { - ret = -ENOMEM; - goto exit; - } - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); -#endif data->type = id->driver_data; - if (data->type == as5712_54x_cpld2 || data->type == as5712_54x_cpld3) { - data->last_chan = chips[data->type].deselectChan; /* force the first selection */ - - /* Now create an adapter for each channel */ - for (chan = 0; chan < chips[data->type].nchans; chan++) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) - force = 0; /* dynamic adap number */ - class = 0; /* no class by default */ - ret = i2c_mux_add_adapter(muxc, force, chan, class); - if (ret) -#else - data->virt_adaps[chan] = i2c_add_mux_adapter(adap, &client->dev, client, 0, chan, - 0, - as5712_54x_cpld_mux_select_chan, - as5712_54x_cpld_mux_deselect_mux); - if (data->virt_adaps[chan] == NULL) -#endif - { - ret = -ENODEV; - dev_err(&client->dev, "failed to register multiplexed adapter %d\n", chan); - goto exit_mux_register; - } - } + data->last_chan = chips[data->type].deselectChan; /* force the first selection */ + mutex_init(&data->update_lock); - dev_info(&client->dev, "registered %d multiplexed busses for I2C mux %s\n", - chan, client->name); - } - /* Register sysfs hooks */ - switch (data->type) - { - case as5712_54x_cpld1: - group = &as5712_54x_cpld1_group; - break; - case as5712_54x_cpld2: - group = &as5712_54x_cpld2_group; - break; - case as5712_54x_cpld3: - group = &as5712_54x_cpld3_group; - break; - default: - break; + /* Now create an adapter for each channel */ + for (num = 0; num < chips[data->type].nchans; num++) { + force = 0; /* dynamic adap number */ + class = 0; /* no class by default */ + + ret = i2c_mux_add_adapter(muxc, force, num, class); + + if (ret) { + dev_err(&client->dev, + "failed to register multiplexed adapter" + " %d as bus %d\n", num, force); + goto add_mux_failed; + } } + /* Register sysfs hooks */ + switch (data->type) { + case as5712_54x_cpld1: + group = &as5712_54x_cpld1_group; + break; + case as5712_54x_cpld2: + group = &as5712_54x_cpld2_group; + break; + case as5712_54x_cpld3: + group = &as5712_54x_cpld3_group; + /* Bring QSFPs out of reset */ + as5712_54x_cpld_write_internal(client, 0x15, 0x3F); + break; + default: + break; + } + if (group) { ret = sysfs_create_group(&client->dev.kobj, group); if (ret) { - goto exit_mux_register; + goto add_mux_failed; } } + if (chips[data->type].nchans) { + dev_info(&client->dev, + "registered %d multiplexed busses for I2C %s\n", + num, client->name); + } + else { + dev_info(&client->dev, + "device %s registered\n", client->name); + } + as5712_54x_cpld_add_client(client); + return 0; -exit_mux_register: -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) +add_mux_failed: i2c_mux_del_adapters(muxc); -#else - for (chan--; chan >= 0; chan--) { - i2c_del_mux_adapter(data->virt_adaps[chan]); - } -#endif - kfree(data); -exit: return ret; } static int as5712_54x_cpld_mux_remove(struct i2c_client *client) { - struct as5712_54x_cpld_data *data = i2c_get_clientdata(client); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) - struct i2c_mux_core *muxc = data->muxc; - - i2c_mux_del_adapters(muxc); -#else - const struct chip_desc *chip = &chips[data->type]; - int chan; + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc); const struct attribute_group *group = NULL; as5712_54x_cpld_remove_client(client); @@ -1364,7 +1142,7 @@ static int as5712_54x_cpld_mux_remove(struct i2c_client *client) case as5712_54x_cpld2: group = &as5712_54x_cpld2_group; break; - case as5712_54x_cpld3: + case as5712_54x_cpld3: group = &as5712_54x_cpld3_group; break; default: @@ -1375,14 +1153,7 @@ static int as5712_54x_cpld_mux_remove(struct i2c_client *client) sysfs_remove_group(&client->dev.kobj, group); } - for (chan = 0; chan < chip->nchans; ++chan) { - if (data->virt_adaps[chan]) { - i2c_del_mux_adapter(data->virt_adaps[chan]); - data->virt_adaps[chan] = NULL; - } - } -#endif - kfree(data); + i2c_mux_del_adapters(muxc); return 0; } @@ -1399,7 +1170,7 @@ static int as5712_54x_cpld_read_internal(struct i2c_client *client, u8 reg) continue; } - break; + break; } return status; @@ -1431,8 +1202,7 @@ int as5712_54x_cpld_read(unsigned short cpld_addr, u8 reg) mutex_lock(&list_lock); - list_for_each(list_node, &cpld_client_list) - { + list_for_each(list_node, &cpld_client_list) { cpld_node = list_entry(list_node, struct cpld_client_node, list); if (cpld_node->client->addr == cpld_addr) { @@ -1455,8 +1225,7 @@ int as5712_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) mutex_lock(&list_lock); - list_for_each(list_node, &cpld_client_list) - { + list_for_each(list_node, &cpld_client_list) { cpld_node = list_entry(list_node, struct cpld_client_node, list); if (cpld_node->client->addr == cpld_addr) { @@ -1471,30 +1240,14 @@ int as5712_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) } EXPORT_SYMBOL(as5712_54x_cpld_write); -#if 0 -int accton_i2c_cpld_mux_get_index(int adap_index) -{ - int i; - - for (i = 0; i < NUM_OF_ALL_CPLD_CHANS; i++) { - if (mux_adap_map[i] == adap_index) { - return i; - } - } - - return -EINVAL; -} -EXPORT_SYMBOL(accton_i2c_cpld_mux_get_index); -#endif - static struct i2c_driver as5712_54x_cpld_mux_driver = { - .driver = { - .name = "as5712_54x_cpld", - .owner = THIS_MODULE, + .driver = { + .name = "as5712_54x_cpld", + .owner = THIS_MODULE, }, - .probe = as5712_54x_cpld_mux_probe, - .remove = as5712_54x_cpld_mux_remove, - .id_table = as5712_54x_cpld_mux_id, + .probe = as5712_54x_cpld_mux_probe, + .remove = as5712_54x_cpld_mux_remove, + .id_table = as5712_54x_cpld_mux_id, }; static int __init as5712_54x_cpld_mux_init(void) @@ -1509,7 +1262,7 @@ static void __exit as5712_54x_cpld_mux_exit(void) } MODULE_AUTHOR("Brandon Chuang "); -MODULE_DESCRIPTION("Accton I2C CPLD mux driver"); +MODULE_DESCRIPTION("Accton as5712-54x CPLD driver"); MODULE_LICENSE("GPL"); module_init(as5712_54x_cpld_mux_init); diff --git a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py index e958cb596862..791409913448 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py +++ b/platform/broadcom/sonic-platform-modules-accton/as5712-54x/utils/accton_as5712_util.py @@ -14,7 +14,6 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . - """ Usage: %(scriptName)s [options] command object @@ -36,6 +35,7 @@ import logging import re import time +import pickle from collections import namedtuple PROJECT_NAME = 'as5712_54x' @@ -62,7 +62,7 @@ 'fan3': ['fan3_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': ['fan5_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, @@ -80,12 +80,19 @@ 'psu': ['psu_present ', 'psu_power_good'] , 'sfp': ['sfp_is_present ', 'sfp_tx_disable']} +QSFP_START = 48 +I2C_BUS_ORDER = -1 + sfp_map = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 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, 52, 54, 51, 53, 55] + +port_cpld_path = [ "/sys/bus/i2c/devices/0-0061/" + ,'/sys/bus/i2c/devices/0-0062/'] + mknod =[ 'echo as5712_54x_cpld1 0x60 > /sys/bus/i2c/devices/i2c-0/new_device', 'echo as5712_54x_cpld2 0x61 > /sys/bus/i2c/devices/i2c-0/new_device', @@ -131,7 +138,7 @@ 'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-63/new_device', #EERPOM -'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-0/new_device', ] FORCE = 0 @@ -207,7 +214,7 @@ def show_set_help(): 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-54 {0|1}\" to set sfp# tx_disable" + print " use \""+ cmd + " sfp 1-48 {0|1}\" to set sfp# tx_disable" sys.exit(0) def show_eeprom_help(): @@ -289,10 +296,28 @@ def i2c_order_check(): status, output = log_os_system(tmp, 0) return order +def update_i2c_order(): + global I2C_BUS_ORDER + + order = i2c_order_check() + pickle.dump(order, open("/tmp/accton_util.p", "wb")) # save it + I2C_BUS_ORDER = order + print "[%s]Detected I2C_BUS_ORDER:%d" % (os.path.basename(__file__), I2C_BUS_ORDER) + +def get_i2c_order(): + global I2C_BUS_ORDER + if I2C_BUS_ORDER < 0: + if os.path.exists("/tmp/accton_util.p"): + I2C_BUS_ORDER = pickle.load(open("/tmp/accton_util.p", "rb")) + else: + update_i2c_order() + def device_install(): global FORCE + global I2C_BUS_ORDER - order = i2c_order_check() + update_i2c_order() + order = I2C_BUS_ORDER # if 0x76 is not exist @i2c-0, use reversed bus order if order: for i in range(0,len(mknod2)): @@ -318,7 +343,10 @@ def device_install(): 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 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: @@ -333,13 +361,10 @@ def device_install(): def device_uninstall(): global FORCE + global I2C_BUS_ORDER - status, output =log_os_system("ls /sys/bus/i2c/devices/0-0070", 0) - if status==0: - I2C_ORDER=1 - else: - I2C_ORDER=0 - + get_i2c_order() + order = I2C_BUS_ORDER 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) @@ -348,7 +373,7 @@ def device_uninstall(): if FORCE == 0: return status - if I2C_ORDER==0: + if order == 0: nodelist = mknod else: nodelist = mknod2 @@ -476,7 +501,7 @@ def show_eeprom(index): if len(ALL_DEVICE)==0: devices_info() node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] - node = node.replace(node.split("/")[-1], 'sfp_eeprom') + node = node.replace(node.split("/")[-1], '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) @@ -498,6 +523,43 @@ def show_eeprom(index): print "**********device no found**********" return + +def get_cpld_path(index): + global I2C_BUS_ORDER + + if I2C_BUS_ORDER < 0: + get_i2c_order() + + if I2C_BUS_ORDER !=0 : + return port_cpld_path[index].replace("0-", "1-") + else: + return port_cpld_path[index] + +def cpld_path_of_port(port_index): + if port_index < 1 and port_index > DEVICE_NO['sfp']: + return None + if port_index < 25: + return get_cpld_path(0) + else: + return get_cpld_path(1) + +def get_path_sfp_tx_dis(port_index): + cpld_p = cpld_path_of_port(port_index) + if cpld_p == None: + return False, '' + else: + dev = cpld_p+"module_tx_disable_"+str(port_index) + return True, dev + +def get_path_sfp_presence(port_index): + cpld_p = cpld_path_of_port(port_index) + if cpld_p == None: + return False, '' + else: + dev = cpld_p+"module_present_"+str(port_index) + return True, dev + + def set_device(args): global DEVICE_NO global ALL_DEVICE @@ -535,7 +597,9 @@ def set_device(args): 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: + #if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + #There no tx_disable for QSFP port + if int(args[1]) > QSFP_START or int(args[1])==0: show_set_help() return if len(args)<2: @@ -546,14 +610,13 @@ def set_device(args): 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 - + port_index = int(args[1]) + ret, dev = get_path_sfp_tx_dis(port_index) + if ret == False: + return False + else: + ret, log = log_os_system("echo "+args[2]+" >"+ dev, 1) + return ret return #get digits inside a string. @@ -562,6 +625,16 @@ def get_value(input): digit = re.findall('\d+', input) return int(digit[0]) +def print_1_device_traversal(i, j, k): + 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: + return func+"="+log+" " + else: + return func+"="+"X"+" " + def device_traversal(): if system_ready()==False: print("System's not ready.") @@ -577,15 +650,26 @@ def device_traversal(): for j in sorted(ALL_DEVICE[i].keys(), key=get_value): print " "+j+":", - 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+" ", - else: - print func+"="+"X"+" ", + if i == 'sfp': + port_index = int(filter(str.isdigit, j)) + for k in (ALL_DEVICE[i][j]): + if k.find('tx_disable')!= -1: + ret, k = get_path_sfp_tx_dis(port_index) + if ret == False: + continue + log = print_1_device_traversal(i, j, k) + print log, + if k.find('present')!= -1: + ret, k = get_path_sfp_presence(port_index) + if ret == False: + continue + log = print_1_device_traversal(i, j, k) + print log, + + else: + for k in (ALL_DEVICE[i][j]): + log = print_1_device_traversal(i, j, k) + print log, print print("----------------------------------------------------------------") diff --git a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/optoe.c b/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/optoe.c deleted file mode 100755 index 16be2fef89b1..000000000000 --- a/platform/broadcom/sonic-platform-modules-accton/as7716-32x/modules/optoe.c +++ /dev/null @@ -1,1148 +0,0 @@ -/* - * optoe.c - A driver to read and write the EEPROM on optical transceivers - * (SFP, QSFP and similar I2C based devices) - * - * Copyright (C) 2014 Cumulus networks Inc. - * Copyright (C) 2017 Finisar Corp. - * - * 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 Freeoftware Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -/* - * Description: - * a) Optical transceiver EEPROM read/write transactions are just like - * the at24 eeproms managed by the at24.c i2c driver - * b) The register/memory layout is up to 256 128 byte pages defined by - * a "pages valid" register and switched via a "page select" - * register as explained in below diagram. - * c) 256 bytes are mapped at a time. 'Lower page 00h' is the first 128 - * bytes of address space, and always references the same - * location, independent of the page select register. - * All mapped pages are mapped into the upper 128 bytes - * (offset 128-255) of the i2c address. - * d) Devices with one I2C address (eg QSFP) use I2C address 0x50 - * (A0h in the spec), and map all pages in the upper 128 bytes - * of that address. - * e) Devices with two I2C addresses (eg SFP) have 256 bytes of data - * at I2C address 0x50, and 256 bytes of data at I2C address - * 0x51 (A2h in the spec). Page selection and paged access - * only apply to this second I2C address (0x51). - * e) The address space is presented, by the driver, as a linear - * address space. For devices with one I2C client at address - * 0x50 (eg QSFP), offset 0-127 are in the lower - * half of address 50/A0h/client[0]. Offset 128-255 are in - * page 0, 256-383 are page 1, etc. More generally, offset - * 'n' resides in page (n/128)-1. ('page -1' is the lower - * half, offset 0-127). - * f) For devices with two I2C clients at address 0x50 and 0x51 (eg SFP), - * the address space places offset 0-127 in the lower - * half of 50/A0/client[0], offset 128-255 in the upper - * half. Offset 256-383 is in the lower half of 51/A2/client[1]. - * Offset 384-511 is in page 0, in the upper half of 51/A2/... - * Offset 512-639 is in page 1, in the upper half of 51/A2/... - * Offset 'n' is in page (n/128)-3 (for n > 383) - * - * One I2c addressed (eg QSFP) Memory Map - * - * 2-Wire Serial Address: 1010000x - * - * Lower Page 00h (128 bytes) - * ===================== - * | | - * | | - * | | - * | | - * | | - * | | - * | | - * | | - * | | - * | | - * |Page Select Byte(127)| - * ===================== - * | - * | - * | - * | - * V - * ------------------------------------------------------------ - * | | | | - * | | | | - * | | | | - * | | | | - * | | | | - * | | | | - * | | | | - * | | | | - * | | | | - * V V V V - * ------------ -------------- --------------- -------------- - * | | | | | | | | - * | Upper | | Upper | | Upper | | Upper | - * | Page 00h | | Page 01h | | Page 02h | | Page 03h | - * | | | (Optional) | | (Optional) | | (Optional | - * | | | | | | | for Cable | - * | | | | | | | Assemblies) | - * | ID | | AST | | User | | | - * | Fields | | Table | | EEPROM Data | | | - * | | | | | | | | - * | | | | | | | | - * | | | | | | | | - * ------------ -------------- --------------- -------------- - * - * The SFF 8436 (QSFP) spec only defines the 4 pages described above. - * In anticipation of future applications and devices, this driver - * supports access to the full architected range, 256 pages. - * - **/ - -/* #define DEBUG 1 */ - -#undef EEPROM_CLASS -#ifdef CONFIG_EEPROM_CLASS -#define EEPROM_CLASS -#endif -#ifdef CONFIG_EEPROM_CLASS_MODULE -#define EEPROM_CLASS -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * The optoe driver is for read/write access to the EEPROM on standard - * I2C based optical transceivers (SFP, QSFP, etc) - * - * While based on the at24 driver, it eliminates code that supports other - * types of I2C EEPROMs, and adds support for pages accessed through the - * page-select register at offset 127. - */ - -struct optoe_platform_data { - u32 byte_len; /* size (sum of all addr) */ - u16 page_size; /* for writes */ - u8 flags; - - void (*setup)(struct memory_accessor *, void *context); - void *context; -#ifdef EEPROM_CLASS - struct eeprom_platform_data *eeprom_data; /* extra data for the eeprom_class */ -#endif -}; - -#ifdef EEPROM_CLASS -#include -#endif - -#include - -/* fundamental unit of addressing for EEPROM */ -#define OPTOE_PAGE_SIZE 128 -/* - * Single address devices (eg QSFP) have 256 pages, plus the unpaged - * low 128 bytes. If the device does not support paging, it is - * only 2 'pages' long. - */ -#define OPTOE_ARCH_PAGES 256 -#define ONE_ADDR_EEPROM_SIZE ((1 + OPTOE_ARCH_PAGES) * OPTOE_PAGE_SIZE) -#define ONE_ADDR_EEPROM_UNPAGED_SIZE (2 * OPTOE_PAGE_SIZE) -/* - * Dual address devices (eg SFP) have 256 pages, plus the unpaged - * low 128 bytes, plus 256 bytes at 0x50. If the device does not - * support paging, it is 4 'pages' long. - */ -#define TWO_ADDR_EEPROM_SIZE ((3 + OPTOE_ARCH_PAGES) * OPTOE_PAGE_SIZE) -#define TWO_ADDR_EEPROM_UNPAGED_SIZE (4 * OPTOE_PAGE_SIZE) - -/* a few constants to find our way around the EEPROM */ -#define OPTOE_PAGE_SELECT_REG 0x7F -#define ONE_ADDR_PAGEABLE_REG 0x02 -#define ONE_ADDR_NOT_PAGEABLE (1<<2) -#define TWO_ADDR_PAGEABLE_REG 0x40 -#define TWO_ADDR_PAGEABLE (1<<4) -#define OPTOE_ID_REG 0 - -/* The maximum length of a port name */ -#define MAX_PORT_NAME_LEN 20 -struct optoe_data { - struct optoe_platform_data chip; - struct memory_accessor macc; - int use_smbus; - char port_name[MAX_PORT_NAME_LEN]; - - /* - * Lock protects against activities from other Linux tasks, - * but not from changes by other I2C masters. - */ - struct mutex lock; - struct bin_attribute bin; - struct attribute_group attr_group; - - u8 *writebuf; - unsigned write_max; - - unsigned num_addresses; - -#ifdef EEPROM_CLASS - struct eeprom_device *eeprom_dev; -#endif - - /* dev_class: ONE_ADDR (QSFP) or TWO_ADDR (SFP) */ - int dev_class; - - struct i2c_client *client[]; -}; - -typedef enum optoe_opcode { - OPTOE_READ_OP = 0, - OPTOE_WRITE_OP = 1 -} optoe_opcode_e; - -/* - * This parameter is to help this driver avoid blocking other drivers out - * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C - * clock, one 256 byte read takes about 1/43 second which is excessive; - * but the 1/170 second it takes at 400 kHz may be quite reasonable; and - * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible. - * - * This value is forced to be a power of two so that writes align on pages. - */ -static unsigned io_limit = OPTOE_PAGE_SIZE; - -/* - * specs often allow 5 msec for a page write, sometimes 20 msec; - * it's important to recover from write timeouts. - */ -static unsigned write_timeout = 25; - -/* - * flags to distinguish one-address (QSFP family) from two-address (SFP family) - * If the family is not known, figure it out when the device is accessed - */ -#define ONE_ADDR 1 -#define TWO_ADDR 2 - -static const struct i2c_device_id optoe_ids[] = { - { "optoe1", ONE_ADDR }, - { "optoe2", TWO_ADDR }, - { "sff8436", ONE_ADDR }, - { "24c04", TWO_ADDR }, - { /* END OF LIST */ } -}; -MODULE_DEVICE_TABLE(i2c, optoe_ids); - -/*-------------------------------------------------------------------------*/ -/* - * This routine computes the addressing information to be used for - * a given r/w request. - * - * Task is to calculate the client (0 = i2c addr 50, 1 = i2c addr 51), - * the page, and the offset. - * - * Handles both single address (eg QSFP) and two address (eg SFP). - * For SFP, offset 0-255 are on client[0], >255 is on client[1] - * Offset 256-383 are on the lower half of client[1] - * Pages are accessible on the upper half of client[1]. - * Offset >383 are in 128 byte pages mapped into the upper half - * - * For QSFP, all offsets are on client[0] - * offset 0-127 are on the lower half of client[0] (no paging) - * Pages are accessible on the upper half of client[1]. - * Offset >127 are in 128 byte pages mapped into the upper half - * - * Callers must not read/write beyond the end of a client or a page - * without recomputing the client/page. Hence offset (within page) - * plus length must be less than or equal to 128. (Note that this - * routine does not have access to the length of the call, hence - * cannot do the validity check.) - * - * Offset within Lower Page 00h and Upper Page 00h are not recomputed - */ - -static uint8_t optoe_translate_offset(struct optoe_data *optoe, - loff_t *offset, struct i2c_client **client) -{ - unsigned page = 0; - - *client = optoe->client[0]; - - /* if SFP style, offset > 255, shift to i2c addr 0x51 */ - if (optoe->dev_class == TWO_ADDR) { - if (*offset > 255) { - /* like QSFP, but shifted to client[1] */ - *client = optoe->client[1]; - *offset -= 256; - } - } - - /* - * if offset is in the range 0-128... - * page doesn't matter (using lower half), return 0. - * offset is already correct (don't add 128 to get to paged area) - */ - if (*offset < OPTOE_PAGE_SIZE) - return page; - - /* note, page will always be positive since *offset >= 128 */ - page = (*offset >> 7)-1; - /* 0x80 places the offset in the top half, offset is last 7 bits */ - *offset = OPTOE_PAGE_SIZE + (*offset & 0x7f); - - return page; /* note also returning client and offset */ -} - -static ssize_t optoe_eeprom_read(struct optoe_data *optoe, - struct i2c_client *client, - char *buf, unsigned offset, size_t count) -{ - struct i2c_msg msg[2]; - u8 msgbuf[2]; - unsigned long timeout, read_time; - int status, i; - - memset(msg, 0, sizeof(msg)); - - switch (optoe->use_smbus) { - case I2C_SMBUS_I2C_BLOCK_DATA: - /*smaller eeproms can work given some SMBus extension calls */ - if (count > I2C_SMBUS_BLOCK_MAX) - count = I2C_SMBUS_BLOCK_MAX; - break; - case I2C_SMBUS_WORD_DATA: - /* Check for odd length transaction */ - count = (count == 1) ? 1 : 2; - break; - case I2C_SMBUS_BYTE_DATA: - count = 1; - break; - default: - /* - * When we have a better choice than SMBus calls, use a - * combined I2C message. Write address; then read up to - * io_limit data bytes. msgbuf is u8 and will cast to our - * needs. - */ - i = 0; - msgbuf[i++] = offset; - - msg[0].addr = client->addr; - msg[0].buf = msgbuf; - msg[0].len = i; - - msg[1].addr = client->addr; - msg[1].flags = I2C_M_RD; - msg[1].buf = buf; - msg[1].len = count; - } - - /* - * Reads fail if the previous write didn't complete yet. We may - * loop a few times until this one succeeds, waiting at least - * long enough for one entire page write to work. - */ - timeout = jiffies + msecs_to_jiffies(write_timeout); - do { - read_time = jiffies; - - switch (optoe->use_smbus) { - case I2C_SMBUS_I2C_BLOCK_DATA: - status = i2c_smbus_read_i2c_block_data(client, offset, - count, buf); - break; - case I2C_SMBUS_WORD_DATA: - status = i2c_smbus_read_word_data(client, offset); - if (status >= 0) { - buf[0] = status & 0xff; - if (count == 2) - buf[1] = status >> 8; - status = count; - } - break; - case I2C_SMBUS_BYTE_DATA: - status = i2c_smbus_read_byte_data(client, offset); - if (status >= 0) { - buf[0] = status; - status = count; - } - break; - default: - status = i2c_transfer(client->adapter, msg, 2); - if (status == 2) - status = count; - } - - dev_dbg(&client->dev, "eeprom read %zu@%d --> %d (%ld)\n", - count, offset, status, jiffies); - - if (status == count) /* happy path */ - return count; - - if (status == -ENXIO) /* no module present */ - return status; - - /* REVISIT: at HZ=100, this is sloooow */ - msleep(1); - } while (time_before(read_time, timeout)); - - return -ETIMEDOUT; -} - -static ssize_t optoe_eeprom_write(struct optoe_data *optoe, - struct i2c_client *client, - const char *buf, - unsigned offset, size_t count) -{ - struct i2c_msg msg; - ssize_t status; - unsigned long timeout, write_time; - unsigned next_page_start; - int i = 0; - - /* write max is at most a page - * (In this driver, write_max is actually one byte!) - */ - if (count > optoe->write_max) - count = optoe->write_max; - - /* shorten count if necessary to avoid crossing page boundary */ - next_page_start = roundup(offset + 1, OPTOE_PAGE_SIZE); - if (offset + count > next_page_start) - count = next_page_start - offset; - - switch (optoe->use_smbus) { - case I2C_SMBUS_I2C_BLOCK_DATA: - /*smaller eeproms can work given some SMBus extension calls */ - if (count > I2C_SMBUS_BLOCK_MAX) - count = I2C_SMBUS_BLOCK_MAX; - break; - case I2C_SMBUS_WORD_DATA: - /* Check for odd length transaction */ - count = (count == 1) ? 1 : 2; - break; - case I2C_SMBUS_BYTE_DATA: - count = 1; - break; - default: - /* If we'll use I2C calls for I/O, set up the message */ - msg.addr = client->addr; - msg.flags = 0; - - /* msg.buf is u8 and casts will mask the values */ - msg.buf = optoe->writebuf; - - msg.buf[i++] = offset; - memcpy(&msg.buf[i], buf, count); - msg.len = i + count; - break; - } - - /* - * Reads fail if the previous write didn't complete yet. We may - * loop a few times until this one succeeds, waiting at least - * long enough for one entire page write to work. - */ - timeout = jiffies + msecs_to_jiffies(write_timeout); - do { - write_time = jiffies; - - switch (optoe->use_smbus) { - case I2C_SMBUS_I2C_BLOCK_DATA: - status = i2c_smbus_write_i2c_block_data(client, - offset, count, buf); - if (status == 0) - status = count; - break; - case I2C_SMBUS_WORD_DATA: - if (count == 2) { - status = i2c_smbus_write_word_data(client, - offset, (u16)((buf[0])|(buf[1] << 8))); - } else { - /* count = 1 */ - status = i2c_smbus_write_byte_data(client, - offset, buf[0]); - } - if (status == 0) - status = count; - break; - case I2C_SMBUS_BYTE_DATA: - status = i2c_smbus_write_byte_data(client, offset, - buf[0]); - if (status == 0) - status = count; - break; - default: - status = i2c_transfer(client->adapter, &msg, 1); - if (status == 1) - status = count; - break; - } - - dev_dbg(&client->dev, "eeprom write %zu@%d --> %ld (%lu)\n", - count, offset, (long int) status, jiffies); - - if (status == count) - return count; - - /* REVISIT: at HZ=100, this is sloooow */ - msleep(1); - } while (time_before(write_time, timeout)); - - return -ETIMEDOUT; -} - - -static ssize_t optoe_eeprom_update_client(struct optoe_data *optoe, - char *buf, loff_t off, - size_t count, optoe_opcode_e opcode) -{ - struct i2c_client *client; - ssize_t retval = 0; - uint8_t page = 0; - loff_t phy_offset = off; - int ret = 0; - - page = optoe_translate_offset(optoe, &phy_offset, &client); - dev_dbg(&client->dev, - "optoe_eeprom_update_client off %lld page:%d phy_offset:%lld, count:%ld, opcode:%d\n", - off, page, phy_offset, (long int) count, opcode); - if (page > 0) { - ret = optoe_eeprom_write(optoe, client, &page, - OPTOE_PAGE_SELECT_REG, 1); - if (ret < 0) { - dev_dbg(&client->dev, - "Write page register for page %d failed ret:%d!\n", - page, ret); - return ret; - } - } - - while (count) { - ssize_t status; - - if (opcode == OPTOE_READ_OP) { - status = optoe_eeprom_read(optoe, client, - buf, phy_offset, count); - } else { - status = optoe_eeprom_write(optoe, client, - buf, phy_offset, count); - } - if (status <= 0) { - if (retval == 0) - retval = status; - break; - } - buf += status; - phy_offset += status; - count -= status; - retval += status; - } - - - if (page > 0) { - /* return the page register to page 0 (why?) */ - page = 0; - ret = optoe_eeprom_write(optoe, client, &page, - OPTOE_PAGE_SELECT_REG, 1); - if (ret < 0) { - dev_err(&client->dev, - "Restore page register to 0 failed:%d!\n", ret); - /* error only if nothing has been transferred */ - if (retval == 0) retval = ret; - } - } - return retval; -} - -/* - * Figure out if this access is within the range of supported pages. - * Note this is called on every access because we don't know if the - * module has been replaced since the last call. - * If/when modules support more pages, this is the routine to update - * to validate and allow access to additional pages. - * - * Returns updated len for this access: - * - entire access is legal, original len is returned. - * - access begins legal but is too long, len is truncated to fit. - * - initial offset exceeds supported pages, return -EINVAL - */ -static ssize_t optoe_page_legal(struct optoe_data *optoe, - loff_t off, size_t len) -{ - struct i2c_client *client = optoe->client[0]; - u8 regval; - int status; - size_t maxlen; - - if (off < 0) return -EINVAL; - if (optoe->dev_class == TWO_ADDR) { - /* SFP case */ - /* if no pages needed, we're good */ - if ((off + len) <= TWO_ADDR_EEPROM_UNPAGED_SIZE) return len; - /* if offset exceeds possible pages, we're not good */ - if (off >= TWO_ADDR_EEPROM_SIZE) return -EINVAL; - /* in between, are pages supported? */ - status = optoe_eeprom_read(optoe, client, ®val, - TWO_ADDR_PAGEABLE_REG, 1); - if (status < 0) return status; /* error out (no module?) */ - if (regval & TWO_ADDR_PAGEABLE) { - /* Pages supported, trim len to the end of pages */ - maxlen = TWO_ADDR_EEPROM_SIZE - off; - } else { - /* pages not supported, trim len to unpaged size */ - if (off >= TWO_ADDR_EEPROM_UNPAGED_SIZE) return -EINVAL; - maxlen = TWO_ADDR_EEPROM_UNPAGED_SIZE - off; - } - len = (len > maxlen) ? maxlen : len; - dev_dbg(&client->dev, - "page_legal, SFP, off %lld len %ld\n", - off, (long int) len); - } else { - /* QSFP case */ - /* if no pages needed, we're good */ - if ((off + len) <= ONE_ADDR_EEPROM_UNPAGED_SIZE) return len; - /* if offset exceeds possible pages, we're not good */ - if (off >= ONE_ADDR_EEPROM_SIZE) return -EINVAL; - /* in between, are pages supported? */ - status = optoe_eeprom_read(optoe, client, ®val, - ONE_ADDR_PAGEABLE_REG, 1); - if (status < 0) return status; /* error out (no module?) */ - if (regval & ONE_ADDR_NOT_PAGEABLE) { - /* pages not supported, trim len to unpaged size */ - if (off >= ONE_ADDR_EEPROM_UNPAGED_SIZE) return -EINVAL; - maxlen = ONE_ADDR_EEPROM_UNPAGED_SIZE - off; - } else { - /* Pages supported, trim len to the end of pages */ - maxlen = ONE_ADDR_EEPROM_SIZE - off; - } - len = (len > maxlen) ? maxlen : len; - dev_dbg(&client->dev, - "page_legal, QSFP, off %lld len %ld\n", - off, (long int) len); - } - return len; -} - -static ssize_t optoe_read_write(struct optoe_data *optoe, - char *buf, loff_t off, size_t len, optoe_opcode_e opcode) -{ - struct i2c_client *client = optoe->client[0]; - int chunk; - int status = 0; - ssize_t retval; - size_t pending_len = 0, chunk_len = 0; - loff_t chunk_offset = 0, chunk_start_offset = 0; - - dev_dbg(&client->dev, - "optoe_read_write: off %lld len:%ld, opcode:%s\n", - off, (long int) len, (opcode == OPTOE_READ_OP) ? "r": "w"); - if (unlikely(!len)) - return len; - - /* - * Read data from chip, protecting against concurrent updates - * from this host, but not from other I2C masters. - */ - mutex_lock(&optoe->lock); - - /* - * Confirm this access fits within the device suppored addr range - */ - status = optoe_page_legal(optoe, off, len); - if (status < 0) { - goto err; - } - len = status; - - /* - * For each (128 byte) chunk involved in this request, issue a - * separate call to sff_eeprom_update_client(), to - * ensure that each access recalculates the client/page - * and writes the page register as needed. - * Note that chunk to page mapping is confusing, is different for - * QSFP and SFP, and never needs to be done. Don't try! - */ - pending_len = len; /* amount remaining to transfer */ - retval = 0; /* amount transferred */ - for (chunk = off >> 7; chunk <= (off + len - 1) >> 7; chunk++) { - - /* - * Compute the offset and number of bytes to be read/write - * - * 1. start at offset 0 (within the chunk), and read/write - * the entire chunk - * 2. start at offset 0 (within the chunk) and read/write less - * than entire chunk - * 3. start at an offset not equal to 0 and read/write the rest - * of the chunk - * 4. start at an offset not equal to 0 and read/write less than - * (end of chunk - offset) - */ - chunk_start_offset = chunk * OPTOE_PAGE_SIZE; - - if (chunk_start_offset < off) { - chunk_offset = off; - if ((off + pending_len) < (chunk_start_offset + - OPTOE_PAGE_SIZE)) - chunk_len = pending_len; - else - chunk_len = OPTOE_PAGE_SIZE - off; - } else { - chunk_offset = chunk_start_offset; - if (pending_len > OPTOE_PAGE_SIZE) - chunk_len = OPTOE_PAGE_SIZE; - else - chunk_len = pending_len; - } - - dev_dbg(&client->dev, - "sff_r/w: off %lld, len %ld, chunk_start_offset %lld, chunk_offset %lld, chunk_len %ld, pending_len %ld\n", - off, (long int) len, chunk_start_offset, chunk_offset, - (long int) chunk_len, (long int) pending_len); - - /* - * note: chunk_offset is from the start of the EEPROM, - * not the start of the chunk - */ - status = optoe_eeprom_update_client(optoe, buf, - chunk_offset, chunk_len, opcode); - if (status != chunk_len) { - /* This is another 'no device present' path */ - dev_dbg(&client->dev, - "optoe_update_client for chunk %d chunk_offset %lld chunk_len %ld failed %d!\n", - chunk, chunk_offset, (long int) chunk_len, status); - goto err; - } - buf += status; - pending_len -= status; - retval += status; - } - mutex_unlock(&optoe->lock); - - return retval; - -err: - mutex_unlock(&optoe->lock); - - return status; -} - -static ssize_t optoe_bin_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, - char *buf, loff_t off, size_t count) -{ - struct i2c_client *client = to_i2c_client(container_of(kobj, - struct device, kobj)); - struct optoe_data *optoe = i2c_get_clientdata(client); - - return optoe_read_write(optoe, buf, off, count, OPTOE_READ_OP); -} - - -static ssize_t optoe_bin_write(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, - char *buf, loff_t off, size_t count) -{ - struct i2c_client *client = to_i2c_client(container_of(kobj, - struct device, kobj)); - struct optoe_data *optoe = i2c_get_clientdata(client); - - return optoe_read_write(optoe, buf, off, count, OPTOE_WRITE_OP); -} -/*-------------------------------------------------------------------------*/ - -/* - * This lets other kernel code access the eeprom data. For example, it - * might hold a board's Ethernet address, or board-specific calibration - * data generated on the manufacturing floor. - */ - -static ssize_t optoe_macc_read(struct memory_accessor *macc, - char *buf, off_t offset, size_t count) -{ - struct optoe_data *optoe = container_of(macc, - struct optoe_data, macc); - - return optoe_read_write(optoe, buf, offset, count, OPTOE_READ_OP); -} - -static ssize_t optoe_macc_write(struct memory_accessor *macc, - const char *buf, off_t offset, size_t count) -{ - struct optoe_data *optoe = container_of(macc, - struct optoe_data, macc); - - return optoe_read_write(optoe, (char *) buf, offset, - count, OPTOE_WRITE_OP); -} - -/*-------------------------------------------------------------------------*/ - -static int optoe_remove(struct i2c_client *client) -{ - struct optoe_data *optoe; - int i; - - optoe = i2c_get_clientdata(client); - sysfs_remove_group(&client->dev.kobj, &optoe->attr_group); - sysfs_remove_bin_file(&client->dev.kobj, &optoe->bin); - - for (i = 1; i < optoe->num_addresses; i++) - i2c_unregister_device(optoe->client[i]); - -#ifdef EEPROM_CLASS - eeprom_device_unregister(optoe->eeprom_dev); -#endif - - kfree(optoe->writebuf); - kfree(optoe); - return 0; -} - -static ssize_t show_port_name(struct device *dev, - struct device_attribute *dattr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct optoe_data *optoe = i2c_get_clientdata(client); - ssize_t count; - - mutex_lock(&optoe->lock); - count = sprintf(buf, "%s\n", optoe->port_name); - mutex_unlock(&optoe->lock); - - return count; -} - -static ssize_t set_port_name(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct optoe_data *optoe = i2c_get_clientdata(client); - char port_name[MAX_PORT_NAME_LEN]; - - /* no checking, this value is not used except by show_port_name */ - - if (sscanf(buf, "%19s", port_name) != 1) - return -EINVAL; - - mutex_lock(&optoe->lock); - strcpy(optoe->port_name, port_name); - mutex_unlock(&optoe->lock); - - return count; -} - -static DEVICE_ATTR(port_name, S_IRUGO | S_IWUSR, - show_port_name, set_port_name); - -static ssize_t show_dev_class(struct device *dev, - struct device_attribute *dattr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct optoe_data *optoe = i2c_get_clientdata(client); - ssize_t count; - - mutex_lock(&optoe->lock); - count = sprintf(buf, "%d\n", optoe->dev_class); - mutex_unlock(&optoe->lock); - - return count; -} - -static ssize_t set_dev_class(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct optoe_data *optoe = i2c_get_clientdata(client); - int dev_class; - - /* - * dev_class is actually the number of sfp ports used, thus - * legal values are "1" (QSFP class) and "2" (SFP class) - */ - if (sscanf(buf, "%d", &dev_class) != 1 || - dev_class < 1 || dev_class > 2) - return -EINVAL; - - mutex_lock(&optoe->lock); - optoe->dev_class = dev_class; - mutex_unlock(&optoe->lock); - - return count; -} - -static DEVICE_ATTR(dev_class, S_IRUGO | S_IWUSR, - show_dev_class, set_dev_class); - -static struct attribute *optoe_attrs[] = { - &dev_attr_port_name.attr, - &dev_attr_dev_class.attr, - NULL, -}; - -static struct attribute_group optoe_attr_group = { - .attrs = optoe_attrs, -}; - -static int optoe_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int err; - int use_smbus = 0; - struct optoe_platform_data chip; - struct optoe_data *optoe; - int num_addresses = 0; - int i = 0; - - if (client->addr != 0x50) { - dev_dbg(&client->dev, "probe, bad i2c addr: 0x%x\n", - client->addr); - err = -EINVAL; - goto exit; - } - - if (client->dev.platform_data) { - chip = *(struct optoe_platform_data *)client->dev.platform_data; - dev_dbg(&client->dev, "probe, chip provided, flags:0x%x; name: %s\n", chip.flags, client->name); - } else { - if (!id->driver_data) { - err = -ENODEV; - goto exit; - } - dev_dbg(&client->dev, "probe, building chip\n"); - chip.flags = 0; - chip.setup = NULL; - chip.context = NULL; -#ifdef EEPROM_CLASS - chip.eeprom_data = NULL; -#endif - } - - /* Use I2C operations unless we're stuck with SMBus extensions. */ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - if (i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { - use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; - } else if (i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_WORD_DATA)) { - use_smbus = I2C_SMBUS_WORD_DATA; - } else if (i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_BYTE_DATA)) { - use_smbus = I2C_SMBUS_BYTE_DATA; - } else { - err = -EPFNOSUPPORT; - goto exit; - } - } - - - /* - * Make room for two i2c clients - */ - num_addresses = 2; - - optoe = kzalloc(sizeof(struct optoe_data) + - num_addresses * sizeof(struct i2c_client *), - GFP_KERNEL); - if (!optoe) { - err = -ENOMEM; - goto exit; - } - - mutex_init(&optoe->lock); - - /* determine whether this is a one-address or two-address module */ - if ((strcmp(client->name, "optoe1") == 0) || - (strcmp(client->name, "sff8436") == 0)) { - /* one-address (eg QSFP) family */ - optoe->dev_class = ONE_ADDR; - chip.byte_len = ONE_ADDR_EEPROM_SIZE; - num_addresses = 1; - } else if ((strcmp(client->name, "optoe2") == 0) || - (strcmp(client->name, "24c04") == 0)) { - /* SFP family */ - optoe->dev_class = TWO_ADDR; - chip.byte_len = TWO_ADDR_EEPROM_SIZE; - } else { /* those were the only two choices */ - err = -EINVAL; - goto exit; - } - - dev_dbg(&client->dev, "dev_class: %d\n", optoe->dev_class); - optoe->use_smbus = use_smbus; - optoe->chip = chip; - optoe->num_addresses = num_addresses; - strcpy(optoe->port_name, "unitialized"); - - /* - * Export the EEPROM bytes through sysfs, since that's convenient. - * By default, only root should see the data (maybe passwords etc) - */ - sysfs_bin_attr_init(&optoe->bin); - optoe->bin.attr.name = "eeprom"; - optoe->bin.attr.mode = S_IRUGO; - optoe->bin.read = optoe_bin_read; - optoe->bin.size = chip.byte_len; - - optoe->macc.read = optoe_macc_read; - - if (!use_smbus || - (i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) || - i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_WRITE_WORD_DATA) || - i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { - /* - * NOTE: AN-2079 - * Finisar recommends that the host implement 1 byte writes - * only since this module only supports 32 byte page boundaries. - * 2 byte writes are acceptable for PE and Vout changes per - * Application Note AN-2071. - */ - unsigned write_max = 1; - - optoe->macc.write = optoe_macc_write; - - optoe->bin.write = optoe_bin_write; - optoe->bin.attr.mode |= S_IWUSR; - - if (write_max > io_limit) - write_max = io_limit; - if (use_smbus && write_max > I2C_SMBUS_BLOCK_MAX) - write_max = I2C_SMBUS_BLOCK_MAX; - optoe->write_max = write_max; - - /* buffer (data + address at the beginning) */ - optoe->writebuf = kmalloc(write_max + 2, GFP_KERNEL); - if (!optoe->writebuf) { - err = -ENOMEM; - goto exit_kfree; - } - } else { - dev_warn(&client->dev, - "cannot write due to controller restrictions."); - } - - optoe->client[0] = client; - - /* use a dummy I2C device for two-address chips */ - for (i = 1; i < num_addresses; i++) { - optoe->client[i] = i2c_new_dummy(client->adapter, - client->addr + i); - if (!optoe->client[i]) { - dev_err(&client->dev, "address 0x%02x unavailable\n", - client->addr + i); - err = -EADDRINUSE; - goto err_struct; - } - } - - /* create the sysfs eeprom file */ - err = sysfs_create_bin_file(&client->dev.kobj, &optoe->bin); - if (err) - goto err_struct; - - optoe->attr_group = optoe_attr_group; - - err = sysfs_create_group(&client->dev.kobj, &optoe->attr_group); - if (err) { - dev_err(&client->dev, "failed to create sysfs attribute group.\n"); - goto err_struct; - } -#ifdef EEPROM_CLASS - optoe->eeprom_dev = eeprom_device_register(&client->dev, - chip.eeprom_data); - if (IS_ERR(optoe->eeprom_dev)) { - dev_err(&client->dev, "error registering eeprom device.\n"); - err = PTR_ERR(optoe->eeprom_dev); - goto err_sysfs_cleanup; - } -#endif - - i2c_set_clientdata(client, optoe); - - dev_info(&client->dev, "%zu byte %s EEPROM, %s\n", - optoe->bin.size, client->name, - optoe->bin.write ? "read/write" : "read-only"); - - if (use_smbus == I2C_SMBUS_WORD_DATA || - use_smbus == I2C_SMBUS_BYTE_DATA) { - dev_notice(&client->dev, "Falling back to %s reads, " - "performance will suffer\n", use_smbus == - I2C_SMBUS_WORD_DATA ? "word" : "byte"); - } - - if (chip.setup) - chip.setup(&optoe->macc, chip.context); - - return 0; - -#ifdef EEPROM_CLASS -err_sysfs_cleanup: - sysfs_remove_group(&client->dev.kobj, &optoe->attr_group); - sysfs_remove_bin_file(&client->dev.kobj, &optoe->bin); -#endif - -err_struct: - for (i = 1; i < num_addresses; i++) { - if (optoe->client[i]) - i2c_unregister_device(optoe->client[i]); - } - - kfree(optoe->writebuf); -exit_kfree: - kfree(optoe); -exit: - dev_dbg(&client->dev, "probe error %d\n", err); - - return err; -} - -/*-------------------------------------------------------------------------*/ - -static struct i2c_driver optoe_driver = { - .driver = { - .name = "optoe", - .owner = THIS_MODULE, - }, - .probe = optoe_probe, - .remove = optoe_remove, - .id_table = optoe_ids, -}; - -static int __init optoe_init(void) -{ - - if (!io_limit) { - pr_err("optoe: io_limit must not be 0!\n"); - return -EINVAL; - } - - io_limit = rounddown_pow_of_two(io_limit); - return i2c_add_driver(&optoe_driver); -} -module_init(optoe_init); - -static void __exit optoe_exit(void) -{ - i2c_del_driver(&optoe_driver); -} -module_exit(optoe_exit); - -MODULE_DESCRIPTION("Driver for optical transceiver (SFP, QSFP, ...) EEPROMs"); -MODULE_AUTHOR("DON BOLLINGER "); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-accton/debian/control b/platform/broadcom/sonic-platform-modules-accton/debian/control index 22faf6d202b8..8b020a6644e0 100755 --- a/platform/broadcom/sonic-platform-modules-accton/debian/control +++ b/platform/broadcom/sonic-platform-modules-accton/debian/control @@ -2,40 +2,33 @@ Source: sonic-accton-platform-modules Section: main Priority: extra Maintainer: Accton network , Accton Network -Build-Depends: debhelper (>= 8.0.0), bzip2 +Build-Depends: debhelper (>= 9), bzip2 Standards-Version: 3.9.3 Package: sonic-platform-accton-as7712-32x Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-accton-as5712-54x Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-accton-as7816-64x Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-accton-as7716-32x Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-accton-as7716-32xb Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-accton-as7312-54x Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-accton-as7326-56x Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 Description: kernel modules for platform devices such as fan, led, sfp