From cbf204ba014ca670b4223f2e36c42afd32c20d09 Mon Sep 17 00:00:00 2001 From: hans-tseng Date: Wed, 28 Mar 2018 00:33:25 +0800 Subject: [PATCH] [device]: add the new platform ag9064 (#23) Signed-off-by: hans --- .../plugins/sfputil.py | 10 +- .../Delta-ag9064/port_config.ini | 132 ++- .../modules/delta_ag9032v1_platform.c | 2 +- .../ag9064/modules/delta_ag9064_platform.c | 758 +++++++++++++++++- .../ag9064/modules/i2c-mei_main.c | 3 +- .../debian/control | 2 +- .../debian/platform-modules-ag9064.init | 4 +- .../debian/platform-modules-ag9064.install | 1 + .../systemd/platform-modules-ag9064.service | 13 + 9 files changed, 840 insertions(+), 85 deletions(-) create mode 100644 platform/broadcom/sonic-platform-modules-delta/systemd/platform-modules-ag9064.service diff --git a/device/delta/x86_64-delta_ag9032v1-r0/plugins/sfputil.py b/device/delta/x86_64-delta_ag9032v1-r0/plugins/sfputil.py index 54d69446b1d8..dc5f8037f26a 100644 --- a/device/delta/x86_64-delta_ag9032v1-r0/plugins/sfputil.py +++ b/device/delta/x86_64-delta_ag9032v1-r0/plugins/sfputil.py @@ -51,7 +51,7 @@ def get_presence(self, port_num): return False try: - reg_file = open("/sys/devices/platform/delta-ag9032v1-cpld.0/sfp_present") + reg_file = open("/sys/devices/platform/delta-ag9032v1-swpld.0/sfp_present") except IOError as e: print "Error: unable to open file: %s" % str(e) return False @@ -76,7 +76,7 @@ def get_low_power_mode(self, port_num): return False try: - reg_file = open("/sys/devices/platform/delta-ag9032v1-cpld.0/sfp_lpmode") + reg_file = open("/sys/devices/platform/delta-ag9032v1-swpld.0/sfp_lpmode") except IOError as e: print "Error: unable to open file: %s" % str(e) @@ -100,7 +100,7 @@ def set_low_power_mode(self, port_num, lpmode): return False try: - reg_file = open("/sys/devices/platform/delta-ag9032v1-cpld.0/sfp_lpmode", "r+") + reg_file = open("/sys/devices/platform/delta-ag9032v1-swpld.0/sfp_lpmode", "r+") except IOError as e: print "Error: unable to open file: %s" % str(e) return False @@ -129,7 +129,7 @@ def set_low_power_mode(self, port_num, lpmode): return True def reset(self, port_num): - QSFP_RESET_REGISTER_DEVICE_FILE = "/sys/devices/platform/delta-ag9032v1-cpld.0/sfp_reset" + QSFP_RESET_REGISTER_DEVICE_FILE = "/sys/devices/platform/delta-ag9032v1-swpld.0/sfp_reset" # Check for invalid port_num if port_num < self.port_start or port_num > self.port_end: @@ -172,4 +172,4 @@ def reset(self, port_num): reg_file.write(hex(reg_value)) reg_file.close() - return True \ No newline at end of file + return True diff --git a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/port_config.ini b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/port_config.ini index 2c4eb341369e..be43857f82b1 100644 --- a/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/port_config.ini +++ b/device/delta/x86_64-delta_ag9064-r0/Delta-ag9064/port_config.ini @@ -1,67 +1,65 @@ -# name lanes alias index -Ethernet0 49,50,51,52 Ethernet1/1 1 -Ethernet4 53,54,55,56 Ethernet2/1 2 -Ethernet8 65,66,67,68 Ethernet3/1 3 -Ethernet12 69,70,71,72 Ethernet4/1 4 -Ethernet16 81,82,83,84 Ethernet5/1 5 -Ethernet20 85,86,87,88 Ethernet6/1 6 -Ethernet24 1,2,3,4 Ethernet7/1 7 -Ethernet28 101,102,103,104 Ethernet8/1 8 -Ethernet32 5,6,7,8 Ethernet9/1 9 -Ethernet36 17,18,19,20 Ethernet10/1 10 -Ethernet40 21,22,23,24 Ethernet11/1 11 -Ethernet44 33,34,35,36 Ethernet12/1 12 -Ethernet48 37,38,39,40 Ethernet13/1 13 -Ethernet52 97,98,99,100 Ethernet14/1 14 -Ethernet56 113,114,115,116 Ethernet15/1 15 -Ethernet60 117,118,119,120 Ethernet16/1 16 -Ethernet64 129,130,131,132 Ethernet17/1 17 -Ethernet68 133,134,135,136 Ethernet18/1 18 -Ethernet72 145,146,147,148 Ethernet19/1 19 -Ethernet76 209,210,211,212 Ethernet20/1 20 -Ethernet80 213,214,215,216 Ethernet21/1 21 -Ethernet84 225,226,227,228 Ethernet22/1 22 -Ethernet88 229,230,231,232 Ethernet23/1 23 -Ethernet92 241,242,243,244 Ethernet24/1 24 -Ethernet96 245,246,247,248 Ethernet25/1 25 -Ethernet100 157,158,159,160 Ethernet26/1 26 -Ethernet104 161,162,163,164 Ethernet27/1 27 -Ethernet108 165,166,167,168 Ethernet28/1 28 -Ethernet112 177,178,179,180 Ethernet29/1 29 -Ethernet116 181,182,183,184 Ethernet30/1 30 -Ethernet120 193,194,195,196 Ethernet31/1 31 -Ethernet124 197,198,199,200 Ethernet32/1 32 -Ethernet128 61,62,63,64 Ethernet33/1 33 -Ethernet132 57,58,59,60 Ethernet34/1 34 -Ethernet136 77,78,79,80 Ethernet35/1 35 -Ethernet140 73,74,75,76 Ethernet36/1 36 -Ethernet144 93,94,95,96 Ethernet37/1 37 -Ethernet148 89,90,91,92 Ethernet38/1 38 -Ethernet152 105,106,107,108 Ethernet39/1 39 -Ethernet156 9,10,11,12 Ethernet40/1 40 -Ethernet160 25,26,27,28 Ethernet41/1 41 -Ethernet164 13,14,15,16 Ethernet42/1 42 -Ethernet168 41,42,43,44 Ethernet43/1 43 -Ethernet172 29,30,31,32 Ethernet44/1 44 -Ethernet176 45,46,47,48 Ethernet45/1 45 -Ethernet180 109,110,111,112 Ethernet46/1 46 -Ethernet184 125,126,127,128 Ethernet47/1 47 -Ethernet188 121,122,123,124 Ethernet48/1 48 -Ethernet192 141,142,143,144 Ethernet49/1 49 -Ethernet196 137,138,139,140 Ethernet50/1 50 -Ethernet200 217,218,219,220 Ethernet51/1 51 -Ethernet204 149,150,151,152 Ethernet52/1 52 -Ethernet208 233,234,235,236 Ethernet53/1 53 -Ethernet212 221,222,223,224 Ethernet54/1 54 -Ethernet216 249,250,251,252 Ethernet55/1 55 -Ethernet220 237,238,239,240 Ethernet56/1 56 -Ethernet224 153,154,155,156 Ethernet57/1 57 -Ethernet228 253,254,255,256 Ethernet58/1 58 -Ethernet232 173,174,175,176 Ethernet59/1 59 -Ethernet236 169,170,171,172 Ethernet60/1 60 -Ethernet240 189,190,191,192 Ethernet61/1 61 -Ethernet244 185,186,187,188 Ethernet62/1 62 -Ethernet248 205,206,207,208 Ethernet63/1 63 -Ethernet252 201,202,203,204 Ethernet64/1 64 -Ethernet256 257 Ethernet65 65 -Ethernet260 259 Ethernet66 66 +# name lanes alias +Ethernet0 49,50,51,52 Ethernet1/1 +Ethernet4 53,54,55,56 Ethernet2/1 +Ethernet8 65,66,67,68 Ethernet3/1 +Ethernet12 69,70,71,72 Ethernet4/1 +Ethernet16 81,82,83,84 Ethernet5/1 +Ethernet20 85,86,87,88 Ethernet6/1 +Ethernet24 1,2,3,4 Ethernet7/1 +Ethernet28 101,102,103,104 Ethernet8/1 +Ethernet32 5,6,7,8 Ethernet9/1 +Ethernet36 17,18,19,20 Ethernet10/1 +Ethernet40 21,22,23,24 Ethernet11/1 +Ethernet44 33,34,35,36 Ethernet12/1 +Ethernet48 37,38,39,40 Ethernet13/1 +Ethernet52 97,98,99,100 Ethernet14/1 +Ethernet56 113,114,115,116 Ethernet15/1 +Ethernet60 117,118,119,120 Ethernet16/1 +Ethernet64 129,130,131,132 Ethernet17/1 +Ethernet68 133,134,135,136 Ethernet18/1 +Ethernet72 145,146,147,148 Ethernet19/1 +Ethernet76 209,210,211,212 Ethernet20/1 +Ethernet80 213,214,215,216 Ethernet21/1 +Ethernet84 225,226,227,228 Ethernet22/1 +Ethernet88 229,230,231,232 Ethernet23/1 +Ethernet92 241,242,243,244 Ethernet24/1 +Ethernet96 245,246,247,248 Ethernet25/1 +Ethernet100 157,158,159,160 Ethernet26/1 +Ethernet104 161,162,163,164 Ethernet27/1 +Ethernet108 165,166,167,168 Ethernet28/1 +Ethernet112 177,178,179,180 Ethernet29/1 +Ethernet116 181,182,183,184 Ethernet30/1 +Ethernet120 193,194,195,196 Ethernet31/1 +Ethernet124 197,198,199,200 Ethernet32/1 +Ethernet128 61,62,63,64 Ethernet33/1 +Ethernet132 57,58,59,60 Ethernet34/1 +Ethernet136 77,78,79,80 Ethernet35/1 +Ethernet140 73,74,75,76 Ethernet36/1 +Ethernet144 93,94,95,96 Ethernet37/1 +Ethernet148 89,90,91,92 Ethernet38/1 +Ethernet152 105,106,107,108 Ethernet39/1 +Ethernet156 9,10,11,12 Ethernet40/1 +Ethernet160 25,26,27,28 Ethernet41/1 +Ethernet164 13,14,15,16 Ethernet42/1 +Ethernet168 41,42,43,44 Ethernet43/1 +Ethernet172 29,30,31,32 Ethernet44/1 +Ethernet176 45,46,47,48 Ethernet45/1 +Ethernet180 109,110,111,112 Ethernet46/1 +Ethernet184 125,126,127,128 Ethernet47/1 +Ethernet188 121,122,123,124 Ethernet48/1 +Ethernet192 141,142,143,144 Ethernet49/1 +Ethernet196 137,138,139,140 Ethernet50/1 +Ethernet200 217,218,219,220 Ethernet51/1 +Ethernet204 149,150,151,152 Ethernet52/1 +Ethernet208 233,234,235,236 Ethernet53/1 +Ethernet212 221,222,223,224 Ethernet54/1 +Ethernet216 249,250,251,252 Ethernet55/1 +Ethernet220 237,238,239,240 Ethernet56/1 +Ethernet224 153,154,155,156 Ethernet57/1 +Ethernet228 253,254,255,256 Ethernet58/1 +Ethernet232 173,174,175,176 Ethernet59/1 +Ethernet236 169,170,171,172 Ethernet60/1 +Ethernet240 189,190,191,192 Ethernet61/1 +Ethernet244 185,186,187,188 Ethernet62/1 +Ethernet248 205,206,207,208 Ethernet63/1 +Ethernet252 201,202,203,204 Ethernet64/1 diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_platform.c b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_platform.c index 520a935561ab..20a91db4c0f9 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_platform.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_platform.c @@ -554,7 +554,7 @@ static int __exit i2c_deivce_remove(struct platform_device *pdev) } if (pdata->client) { - parent = i2c_get_adapter(pdata->parent); + parent = (pdata->client)->adapter; i2c_unregister_device(pdata->client); i2c_put_adapter(parent); } diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_platform.c b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_platform.c index 38fb82d443c7..f4222907d4f2 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_platform.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/delta_ag9064_platform.c @@ -776,7 +776,7 @@ static int __exit i2c_deivce_remove(struct platform_device *pdev) } if (pdata->client) { - parent = i2c_get_adapter(pdata->parent); + parent = (pdata->client)->adapter; i2c_unregister_device(pdata->client); i2c_put_adapter(parent); } @@ -799,7 +799,7 @@ static struct platform_driver i2c_device_driver = { struct swpld_mux_platform_data { int parent; int base_nr; - struct i2c_client *cpld; +// struct i2c_client *cpld; }; struct swpld_mux { @@ -812,7 +812,7 @@ static struct swpld_mux_platform_data ag9064_swpld_mux_platform_data[] = { { .parent = BUS9, .base_nr = BUS9_BASE_NUM, - .cpld = NULL, +// .cpld = NULL, }, }; @@ -827,11 +827,36 @@ static struct platform_device ag9064_swpld_mux[] = }, }, }; - +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) static int swpld_mux_select(struct i2c_adapter *adap, void *data, u8 chan) { + uint8_t cmd_data[4]={0}; struct swpld_mux *mux = data; + uint8_t set_cmd; + int cmd_data_len; + + if ( mux->data.base_nr == BUS9_BASE_NUM ) + { + set_cmd = CMD_SETDATA; + cmd_data[0] = BMC_BUS_5; + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_PORT_MUX_REG; + cmd_data[3] = chan + 1; + cmd_data_len = sizeof(cmd_data); + // return 0; + return dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + } + else + { + printk(KERN_ERR "Swpld mux QSFP select port error\n"); + return 0; + } +} +#else +static int swpld_mux_select(struct i2c_mux_core *muxc, u32 chan) +{ uint8_t cmd_data[4]={0}; + struct swpld_mux *mux = i2c_mux_priv(muxc); uint8_t set_cmd; int cmd_data_len; @@ -844,14 +869,18 @@ static int swpld_mux_select(struct i2c_adapter *adap, void *data, u8 chan) cmd_data[3] = chan + 1; cmd_data_len = sizeof(cmd_data); return dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + return 0; } else { printk(KERN_ERR "Swpld mux QSFP select port error\n"); return 0; } + } +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) static int __init swpld_mux_probe(struct platform_device *pdev) { struct swpld_mux *mux; @@ -926,7 +955,76 @@ static int __init swpld_mux_probe(struct platform_device *pdev) return ret; } +#else // #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) +static int __init swpld_mux_probe(struct platform_device *pdev) +{ + struct i2c_mux_core *muxc; + struct swpld_mux *mux; + struct swpld_mux_platform_data *pdata; + struct i2c_adapter *parent; + int i, ret, dev_num; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "SWPLD platform data not found\n"); + return -ENODEV; + } + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) { + printk(KERN_ERR "Failed to allocate memory for mux\n"); + return -ENOMEM; + } + mux->data = *pdata; + + parent = i2c_get_adapter(pdata->parent); + if (!parent) { + kfree(mux); + dev_err(&pdev->dev, "Parent adapter (%d) not found\n", pdata->parent); + return -ENODEV; + } + /* Judge bus number to decide how many devices*/ + switch (pdata->parent) { + case BUS9: + dev_num = BUS9_DEV_NUM; + break; + default : + dev_num = DEFAULT_NUM; + break; + } + + muxc = i2c_mux_alloc(parent, &pdev->dev, dev_num, 0, 0,swpld_mux_select, NULL); + if (!muxc) { + ret = -ENOMEM; + goto alloc_failed; + } + muxc->priv = mux; + platform_set_drvdata(pdev, muxc); + + for (i = 0; i < dev_num; i++) + { + int nr = pdata->base_nr + i; + unsigned int class = 0; + ret = i2c_mux_add_adapter(muxc, nr, i, class); + if (ret) { + dev_err(&pdev->dev, "Failed to add adapter %d\n", i); + goto add_adapter_failed; + } + } + dev_info(&pdev->dev, "%d port mux on %s adapter\n", dev_num, parent->name); + return 0; + +add_adapter_failed: + i2c_mux_del_adapters(muxc); +alloc_failed2: + kfree(mux); +alloc_failed: + i2c_put_adapter(parent); + + return ret; +} +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) static int __exit swpld_mux_remove(struct platform_device *pdev) { int i; @@ -966,6 +1064,18 @@ static int __exit swpld_mux_remove(struct platform_device *pdev) return 0; } +#else // #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) +static int __exit swpld_mux_remove(struct platform_device *pdev) +{ + struct i2c_mux_core *muxc = platform_get_drvdata(pdev); + struct i2c_adapter *parent=muxc->parent; + + i2c_mux_del_adapters(muxc); + i2c_put_adapter(parent); + + return 0; +} +#endif static struct platform_driver swpld_mux_driver = { .probe = swpld_mux_probe, @@ -977,13 +1087,627 @@ static struct platform_driver swpld_mux_driver = { }; /*---------------- MUX - end ------------- */ +/*---------------- CPLD - start ------------- */ + +/* CPLD -- device */ + +static ssize_t get_present(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + uint8_t cmd_data[4]={0}; + int ret; + u64 data = 0; + uint8_t set_cmd; + int cmd_data_len; + + set_cmd = CMD_GETDATA; + + /*QSFP1~8*/ + cmd_data[0] = BMC_BUS_5; + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_PRESENCE_1; + cmd_data[3] = 1; + cmd_data_len = sizeof(cmd_data); + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + ret=0; + data = (u64)(ret & 0xff); + + /*QSFP9~16*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_PRESENCE_2; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); +// ret=0; + data |= (u64)(ret & 0xff) << 8; + + /*QSFP17~24*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_PRESENCE_3; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 16; + + /*QSFP25~32*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_PRESENCE_4; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 24; + + /*QSFP33~40*/ + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_PRESENCE_5; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 32; + + /*QSFP41~48*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_PRESENCE_6; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 40; + + /*QSFP49~56*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_PRESENCE_7; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 48; + + /*QSFP57~64*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_PRESENCE_8; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 56; + + return sprintf(buf, "0x%016llx\n", data); +} + +static ssize_t get_lpmode(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + uint8_t cmd_data[4]={0}; + int ret; + u64 data = 0; + uint8_t set_cmd; + int cmd_data_len; + + set_cmd = CMD_GETDATA; + ret=0; + /*QSFP1~8*/ + cmd_data[0] = BMC_BUS_5; + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_LP_MODE_1; + cmd_data[3] = 1; + cmd_data_len = sizeof(cmd_data); + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data = (u64)(ret & 0xff); + + /*QSFP9~16*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_LP_MODE_2; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 8; + + /*QSFP17~24*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_LP_MODE_3; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 16; + + /*QSFP25~32*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_LP_MODE_4; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 24; + + /*QSFP33~40*/ + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_LP_MODE_5; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 32; + + /*QSFP41~48*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_LP_MODE_6; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 40; + + /*QSFP49~56*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_LP_MODE_7; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 48; + + /*QSFP57~64*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_LP_MODE_8; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 56; + + return sprintf(buf, "0x%016llx\n", data); +} + +static ssize_t get_reset(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + uint8_t cmd_data[4]={0}; + int ret; + u64 data = 0; + uint8_t set_cmd; + int cmd_data_len; + + set_cmd = CMD_GETDATA; + + /*QSFP1~8*/ + cmd_data[0] = BMC_BUS_5; + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_RESET_1; + cmd_data[3] = 1; + cmd_data_len = sizeof(cmd_data); + ret=0; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data = (u64)(ret & 0xff); + + /*QSFP9~16*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_RESET_2; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 8; + + /*QSFP17~24*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_RESET_3; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 16; + + /*QSFP25~32*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_RESET_4; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 24; + + /*QSFP33~40*/ + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_RESET_5; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 32; + + /*QSFP41~48*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_RESET_6; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 40; + + /*QSFP49~56*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_RESET_7; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 48; + + /*QSFP57~64*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_RESET_8; + ret = dni_bmc_cmd(set_cmd, cmd_data, cmd_data_len); + data |= (u64)(ret & 0xff) << 56; + + return sprintf(buf, "0x%016llx\n", data); +} + +static ssize_t get_response(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + uint8_t cmd_data[4]={0}; + int ret; + u64 data = 0; + uint8_t set_cmd; + int cmd_data_len; + + set_cmd = CMD_GETDATA; + + /*QSFP1~8*/ + cmd_data[0] = BMC_BUS_5; + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_RESPONSE_1; + cmd_data[3] = 1; + cmd_data_len = sizeof(cmd_data); + ret = 0; + data = (u64)(ret & 0xff); + + /*QSFP9~16*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_RESPONSE_2; + data |= (u64)(ret & 0xff) << 8; + + /*QSFP17~24*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_RESPONSE_3; + data |= (u64)(ret & 0xff) << 16; + + /*QSFP25~32*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_RESPONSE_4; + data |= (u64)(ret & 0xff) << 24; + + /*QSFP33~40*/ + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_RESPONSE_5; + data |= (u64)(ret & 0xff) << 32; + + /*QSFP41~48*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_RESPONSE_6; + data |= (u64)(ret & 0xff) << 40; + + /*QSFP49~56*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_RESPONSE_7; + data |= (u64)(ret & 0xff) << 48; + + /*QSFP57~64*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_RESPONSE_8; + data |= (u64)(ret & 0xff) << 56; + + return sprintf(buf, "0x%016llx\n", data); +} + +static ssize_t get_interrupt(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + uint8_t cmd_data[4]={0}; + int ret; + u64 data = 0; + uint8_t set_cmd; + int cmd_data_len; + + set_cmd = CMD_GETDATA; + + /*QSFP1~8*/ + cmd_data[0] = BMC_BUS_5; + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_INTERRUPT_1; + cmd_data[3] = 1; + cmd_data_len = sizeof(cmd_data); + ret=0; + data = (u64)(ret & 0xff); + + /*QSFP9~16*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_INTERRUPT_2; + data |= (u64)(ret & 0xff) << 8; + + /*QSFP17~24*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_INTERRUPT_3; + data |= (u64)(ret & 0xff) << 16; + + /*QSFP25~32*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_INTERRUPT_4; + data |= (u64)(ret & 0xff) << 24; + + /*QSFP33~40*/ + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_INTERRUPT_5; + data |= (u64)(ret & 0xff) << 32; + + /*QSFP41~48*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_INTERRUPT_6; + data |= (u64)(ret & 0xff) << 40; + + /*QSFP49~56*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_INTERRUPT_7; + data |= (u64)(ret & 0xff) << 48; + + /*QSFP57~64*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_INTERRUPT_8; + data |= (u64)(ret & 0xff) << 56; + + return sprintf(buf, "0x%016llx\n", data); +} + + +static ssize_t set_lpmode(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + uint8_t cmd_data[4]={0}; + unsigned long long set_data; + int err; + + err = kstrtoull(buf, 16, &set_data); + if (err){ + return err; + } + uint8_t set_cmd; + int cmd_data_len; + + set_cmd = CMD_SETDATA; + /*QSFP1~8*/ + cmd_data[0] = BMC_BUS_5; + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_LP_MODE_1; + cmd_data[3] = (set_data & 0xff); + cmd_data_len = sizeof(cmd_data); + + /*QSFP9~16*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_LP_MODE_2; + cmd_data[3] = ((set_data >> 8 ) & 0xff); + + /*QSFP17~24*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_LP_MODE_3; + cmd_data[3] = ((set_data >> 16 ) & 0xff); + + /*QSFP25~32*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_LP_MODE_4; + cmd_data[3] = ((set_data >> 24 ) & 0xff); + + /*QSFP33~40*/ + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_LP_MODE_5; + cmd_data[3] = ((set_data >> 32 ) & 0xff); + + /*QSFP41~48*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_LP_MODE_6; + cmd_data[3] = ((set_data >> 40 ) & 0xff); + + /*QSFP49~56*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_LP_MODE_7; + cmd_data[3] = ((set_data >> 48 ) & 0xff); + + /*QSFP57~64*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_LP_MODE_8; + cmd_data[3] = ((set_data >> 56 ) & 0xff); + + return count; +} + +static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + uint8_t cmd_data[4]={0}; + unsigned long long set_data; + int err; + + err = kstrtoull(buf, 16, &set_data); + if (err){ + return err; + } + uint8_t set_cmd; + int cmd_data_len; + + set_cmd = CMD_SETDATA; + + /*QSFP1~8*/ + cmd_data[0] = BMC_BUS_5; + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_RESET_1; + cmd_data[3] = (set_data & 0xff); + cmd_data_len = sizeof(cmd_data); + + /*QSFP9~16*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_RESET_2; + cmd_data[3] = ((set_data >> 8 ) & 0xff); + + /*QSFP17~24*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_RESET_3; + cmd_data[3] = ((set_data >> 16 ) & 0xff); + + /*QSFP25~32*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_RESET_4; + cmd_data[3] = ((set_data >> 24 ) & 0xff); + + /*QSFP33~40*/ + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_RESET_5; + cmd_data[3] = ((set_data >> 32 ) & 0xff); + + /*QSFP41~48*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_RESET_6; + cmd_data[3] = ((set_data >> 40 ) & 0xff); + + /*QSFP49~56*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_RESET_7; + cmd_data[3] = ((set_data >> 48 ) & 0xff); + + /*QSFP57~64*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_RESET_8; + cmd_data[3] = ((set_data >> 56 ) & 0xff); + + return count; +} + +static ssize_t set_response(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + uint8_t cmd_data[4]={0}; + unsigned long long set_data; + int err; + + err = kstrtoull(buf, 16, &set_data); + if (err){ + return err; + } + uint8_t set_cmd; + int cmd_data_len; + + set_cmd = CMD_SETDATA; + + /*QSFP1~8*/ + cmd_data[0] = BMC_BUS_5; + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_RESPONSE_1; + cmd_data[3] = (set_data & 0xff); + cmd_data_len = sizeof(cmd_data); + + /*QSFP9~16*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_RESPONSE_2; + cmd_data[3] = ((set_data >> 8 ) & 0xff); + + /*QSFP17~24*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_RESPONSE_3; + cmd_data[3] = ((set_data >> 16 ) & 0xff); + + /*QSFP25~32*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_RESPONSE_4; + cmd_data[3] = ((set_data >> 24 ) & 0xff); + + /*QSFP33~40*/ + cmd_data[1] = SWPLD1_ADDR; + cmd_data[2] = QSFP_RESPONSE_5; + cmd_data[3] = ((set_data >> 32 ) & 0xff); + + /*QSFP41~48*/ + cmd_data[1] = SWPLD2_ADDR; + cmd_data[2] = QSFP_RESPONSE_6; + cmd_data[3] = ((set_data >> 40 ) & 0xff); + + /*QSFP49~56*/ + cmd_data[1] = SWPLD4_ADDR; + cmd_data[2] = QSFP_RESPONSE_7; + cmd_data[3] = ((set_data >> 48 ) & 0xff); + + /*QSFP57~64*/ + cmd_data[1] = SWPLD3_ADDR; + cmd_data[2] = QSFP_RESPONSE_8; + cmd_data[3] = ((set_data >> 56 ) & 0xff); + + return count; +} + +static DEVICE_ATTR(qsfp_present, S_IRUGO, get_present, NULL); +static DEVICE_ATTR(qsfp_lpmode, S_IWUSR | S_IRUGO, get_lpmode, set_lpmode); +static DEVICE_ATTR(qsfp_reset, S_IWUSR | S_IRUGO, get_reset, set_reset); +static DEVICE_ATTR(qsfp_modsel, S_IWUSR | S_IRUGO, get_response, set_response); +static DEVICE_ATTR(qsfp_interrupt, S_IRUGO, get_interrupt, NULL); + +static struct attribute *ag9064_cpld_attrs[] = { + &dev_attr_qsfp_present.attr, + &dev_attr_qsfp_lpmode.attr, + &dev_attr_qsfp_reset.attr, + &dev_attr_qsfp_modsel.attr, + &dev_attr_qsfp_interrupt.attr, + NULL, +}; + +static struct attribute_group ag9064_cpld_attr_grp = { + .attrs = ag9064_cpld_attrs, +}; + +enum cpld_type { + system_cpld, +}; + +struct cpld_platform_data { + int reg_addr; + struct i2c_client *client; +}; + +static struct cpld_platform_data ag9064_cpld_platform_data[] = { + [system_cpld] = { + .reg_addr = CPLD_REG, + }, +}; + +static struct platform_device ag9064_cpld = { + .name = "delta-ag9064-cpld", + .id = 0, + .dev = { + .platform_data = ag9064_cpld_platform_data, + .release = device_release + }, +}; + +static int __init cpld_probe(struct platform_device *pdev) +{ + struct cpld_platform_data *pdata; + struct i2c_adapter *parent; + int ret; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "CPLD platform data not found\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(BUS7); + if (!parent) { + printk(KERN_WARNING "Parent adapter (%d) not found\n",BUS7); + return -ENODEV; + } + + pdata[system_cpld].client = i2c_new_dummy(parent, pdata[system_cpld].reg_addr); + if (!pdata[system_cpld].client) { + printk(KERN_WARNING "Fail to create dummy i2c client for addr %d\n", pdata[system_cpld].reg_addr); + goto error; + } + + ret = sysfs_create_group(&pdev->dev.kobj, &ag9064_cpld_attr_grp); + if (ret) { + printk(KERN_WARNING "Fail to create cpld attribute group"); + goto error; + } + + return 0; + +error: + i2c_unregister_device(pdata[system_cpld].client); + i2c_put_adapter(parent); + + return -ENODEV; +} + +static int __exit cpld_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent = NULL; + struct cpld_platform_data *pdata = pdev->dev.platform_data; + sysfs_remove_group(&pdev->dev.kobj, &ag9064_cpld_attr_grp); + + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + } + else { + if (pdata[system_cpld].client) { + if (!parent) { + parent = (pdata[system_cpld].client)->adapter; + } + i2c_unregister_device(pdata[system_cpld].client); + } + } + i2c_put_adapter(parent); + + return 0; +} + +static struct platform_driver cpld_driver = { + .probe = cpld_probe, + .remove = __exit_p(cpld_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-ag9064-cpld", + }, +}; + +/*---------------- CPLD - end ------------- */ + /*---------------- module initialization ------------- */ -static void __init delta_ag9064_platform_init(void) +static int __init delta_ag9064_platform_init(void) { struct i2c_client *client; struct i2c_adapter *adapter; struct swpld_mux_platform_data *swpld_pdata; + struct cpld_platform_data * cpld_pdata; int ret,i = 0; printk("ag9064_platform module initialization\n"); @@ -997,6 +1721,12 @@ static void __init delta_ag9064_platform_init(void) printk(KERN_WARNING "Fail to create IPMI user\n"); } + ret = platform_driver_register(&cpld_driver); + if (ret) { + printk(KERN_WARNING "Fail to register cpld driver\n"); + goto error_cpld_driver; + } + // register the mux prob which call the SWPLD ret = platform_driver_register(&swpld_mux_driver); if (ret) { @@ -1011,9 +1741,15 @@ static void __init delta_ag9064_platform_init(void) goto error_i2c_device_driver; } + // register the CPLD + ret = platform_device_register(&ag9064_cpld); + if (ret) { + printk(KERN_WARNING "Fail to create cpld device\n"); + goto error_ag9064_cpld; + } + swpld_pdata = ag9064_swpld_mux[0].dev.platform_data; - //swpld_pdata->cpld = cpld_pdata[system_cpld].client; - ret = platform_device_register(&ag9064_swpld_mux); + ret = platform_device_register(&ag9064_swpld_mux[0]); if (ret) { printk(KERN_WARNING "Fail to create swpld mux\n"); goto error_ag9064_swpld_mux; @@ -1044,10 +1780,14 @@ static void __init delta_ag9064_platform_init(void) for (; i >= 0; i--) { platform_device_unregister(&ag9064_swpld_mux); } + platform_driver_unregister(&ag9064_cpld); +error_ag9064_cpld: platform_driver_unregister(&i2c_device_driver); error_i2c_device_driver: platform_driver_unregister(&swpld_mux_driver); error_swpld_mux_driver: + platform_driver_unregister(&cpld_driver); +error_cpld_driver: return ret; } @@ -1060,8 +1800,10 @@ static void __exit delta_ag9064_platform_exit(void) } platform_device_unregister(&ag9064_swpld_mux); + platform_device_unregister(&ag9064_cpld); platform_driver_unregister(&i2c_device_driver); platform_driver_unregister(&swpld_mux_driver); + platform_driver_unregister(&cpld_driver); i2c_unregister_device(i2c_client_9548); } @@ -1070,4 +1812,4 @@ module_exit(delta_ag9064_platform_exit); MODULE_DESCRIPTION("DELTA ag9064 Platform Support"); MODULE_AUTHOR("Johnson Lu "); -MODULE_LICENSE("GPL"); \ No newline at end of file +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/i2c-mei_main.c b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/i2c-mei_main.c index 6a412a783c54..a5dbbd22b4a5 100644 --- a/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/i2c-mei_main.c +++ b/platform/broadcom/sonic-platform-modules-delta/ag9064/modules/i2c-mei_main.c @@ -147,9 +147,10 @@ static int mei_TxRx(u8 sensor_bus, u16 addr, u8 command, char read_write, int int i = 0; struct mei_msg * msg; - unsigned char blen; +// unsigned char blen; UINT32 timeout, dwTimeout; + UINT32 blen; HECI_DEVICE sHeciDev; recv_buf = kmalloc(sizeof(unsigned char) * (32), GFP_KERNEL); diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/control b/platform/broadcom/sonic-platform-modules-delta/debian/control index 06ac0c80a87d..bb543a5a70ae 100644 --- a/platform/broadcom/sonic-platform-modules-delta/debian/control +++ b/platform/broadcom/sonic-platform-modules-delta/debian/control @@ -12,7 +12,7 @@ Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9064 Architecture: amd64 -Depends: linux-image-3.16.0-5-amd64 +Depends: linux-image-4.9.0-5-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag5648 diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9064.init b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9064.init index dee41fd6f457..57665353e3c7 100755 --- a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9064.init +++ b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9064.init @@ -20,11 +20,11 @@ start) modprobe i2c-dev modprobe i2c-i801 modprobe i2c-ismt + modprobe ipmi_devintf + modprobe ipmi_si ports=0xca2 modprobe i2c-mei modprobe i2c-mux-pca954x modprobe at24 - modprobe ipmi_devintf - modprobe ipmi_si trydefaults=1 modprobe delta_ag9064_platform modprobe delta_ag9064_cpld modprobe delta_ag9064_swpld diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9064.install b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9064.install index 7776ea509487..ad7c793da3c0 100644 --- a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9064.install +++ b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9064.install @@ -1 +1,2 @@ ag9064/cfg/ag9064-modules.conf etc/modules-load.d +systemd/platform-modules-ag9064.service lib/systemd/system diff --git a/platform/broadcom/sonic-platform-modules-delta/systemd/platform-modules-ag9064.service b/platform/broadcom/sonic-platform-modules-delta/systemd/platform-modules-ag9064.service new file mode 100644 index 000000000000..80f6836bfdbc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/systemd/platform-modules-ag9064.service @@ -0,0 +1,13 @@ +[Unit] +Description=Delta ag9064 Platform modules +After=local-fs.target +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-ag9064 start +ExecStop=-/etc/init.d/platform-modules-ag9064 stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target