support platform DELTA AG7648

This commit is contained in:
Dave Hu
2017-04-26 09:40:01 -04:00
parent fbc38a58b5
commit 6209c06aa1
51 changed files with 4691 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
*x86*64*delta*ag7648*.mk
onlpdump.mk

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=delta BASENAME=x86-64-delta-ag7648 ARCH=amd64 KERNELS="onl-kernel-3.16-lts-x86-64-all:amd64"

View File

@@ -0,0 +1 @@
lib

View File

@@ -0,0 +1,6 @@
KERNELS := onl-kernel-3.16-lts-x86-64-all:amd64
KMODULES := $(wildcard *.c)
VENDOR := delta
BASENAME := x86-64-delta-ag7648
ARCH := x86_64
include $(ONL)/make/kmodule.mk

View File

@@ -0,0 +1,245 @@
/*
* An I2C multiplexer dirver for delta ag7648 CPLD
*
* Copyright (C) 2015 Delta Technology Corporation.
* Brandon Chuang <brandon_chuang@delta.com.tw>
*
* This module supports the delta cpld that hold the channel select
* mechanism for other i2c slave devices, such as SFP.
* This includes the:
* Delta ag7648c CPLD1/CPLD2/CPLD3
*
* Based on:
* pca954x.c from Kumar Gala <galak@kernel.crashing.org>
* Copyright (C) 2006
*
* Based on:
* pca954x.c from Ken Harrenstien
* Copyright (C) 2004 Google, Inc. (Ken Harrenstien)
*
* Based on:
* i2c-virtual_cb.c from Brian Kuschak <bkuschak@yahoo.com>
* and
* pca9540.c from Jean Delvare <khali@linux-fr.org>.
*
* 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.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/version.h>
#define CTRL_CPLD_BUS 0x2
#define CTRL_CPLD_I2C_ADDR 0x32
#define PARENT_CHAN 0x4
#define NUM_OF_CPLD_CHANS 0x30
#define CPLD_CHANNEL_SELECT_REG 0x11
#define CPLD_CHANNEL_SELECT_MASK 0x3f
#define CPLD_CHANNEL_SELECT_OFFSET 0x0
#define CPLD_DESELECT_CHANNEL 0xff
#define CPLD_MUX_MAX_NCHANS 0x30
enum cpld_mux_type {
delta_cpld_mux
};
struct delta_i2c_cpld_mux {
enum cpld_mux_type type;
struct i2c_adapter *virt_adaps[CPLD_MUX_MAX_NCHANS];
u8 last_chan; /* last register value */
};
struct chip_desc {
u8 nchans;
u8 deselectChan;
};
/* Provide specs for the PCA954x types we know about */
static const struct chip_desc chips[] = {
[delta_cpld_mux] = {
.nchans = NUM_OF_CPLD_CHANS,
.deselectChan = CPLD_DESELECT_CHANNEL,
}
};
static struct delta_i2c_cpld_mux *cpld_mux_data;
static struct device dump_dev;
/* 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 delta_i2c_cpld_mux_reg_write(struct i2c_adapter *adap,
struct i2c_client *client, u8 val)
{
unsigned long orig_jiffies;
unsigned short flags;
union i2c_smbus_data data;
struct i2c_adapter *ctrl_adap;
int try;
s32 res = -EIO;
u8 reg_val = 0;
data.byte = val;
flags = 0;
ctrl_adap = i2c_get_adapter(CTRL_CPLD_BUS);
if (!ctrl_adap)
return res;
// try to lock it
if (ctrl_adap->algo->smbus_xfer) {
/* Retry automatically on arbitration loss */
orig_jiffies = jiffies;
for (res = 0, try = 0; try <= ctrl_adap->retries; try++) {
// read first
res = ctrl_adap->algo->smbus_xfer(ctrl_adap, CTRL_CPLD_I2C_ADDR, flags,
I2C_SMBUS_READ, CPLD_CHANNEL_SELECT_REG,
I2C_SMBUS_BYTE_DATA, &data);
if (res && res != -EAGAIN)
break;
// modify the field we wanted
data.byte &= ~(CPLD_CHANNEL_SELECT_MASK << CPLD_CHANNEL_SELECT_OFFSET);
reg_val |= (((val + 1)& CPLD_CHANNEL_SELECT_MASK) << CPLD_CHANNEL_SELECT_OFFSET);
data.byte |= reg_val;
// modify the register
res = ctrl_adap->algo->smbus_xfer(ctrl_adap, CTRL_CPLD_I2C_ADDR, flags,
I2C_SMBUS_WRITE, CPLD_CHANNEL_SELECT_REG,
I2C_SMBUS_BYTE_DATA, &data);
if (res && res != -EAGAIN)
break;
if (time_after(jiffies,
orig_jiffies + ctrl_adap->timeout))
break;
}
}
return res;
}
static int delta_i2c_cpld_mux_select_chan(struct i2c_adapter *adap,
void *client, u32 chan)
{
u8 regval;
int ret = 0;
regval = chan;
/* Only select the channel if its different from the last channel */
if (cpld_mux_data->last_chan != regval) {
ret = delta_i2c_cpld_mux_reg_write(NULL, NULL, regval);
cpld_mux_data->last_chan = regval;
}
return ret;
}
static int delta_i2c_cpld_mux_deselect_mux(struct i2c_adapter *adap,
void *client, u32 chan)
{
/* Deselect active channel */
cpld_mux_data->last_chan = chips[cpld_mux_data->type].deselectChan;
return delta_i2c_cpld_mux_reg_write(NULL, NULL, cpld_mux_data->last_chan);
}
/*
* I2C init/probing/exit functions
*/
static int __delta_i2c_cpld_mux_init(void)
{
struct i2c_adapter *adap = i2c_get_adapter(PARENT_CHAN);
int chan=0;
int ret = -ENODEV;
memset (&dump_dev, 0, sizeof(dump_dev));
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
goto err;
if (!adap)
goto err;
cpld_mux_data = kzalloc(sizeof(struct delta_i2c_cpld_mux), GFP_KERNEL);
if (!cpld_mux_data) {
ret = -ENOMEM;
goto err;
}
cpld_mux_data->type = delta_cpld_mux;
cpld_mux_data->last_chan = chips[cpld_mux_data->type].deselectChan; /* force the first selection */
/* Now create an adapter for each channel */
for (chan = 0; chan < NUM_OF_CPLD_CHANS; chan++) {
cpld_mux_data->virt_adaps[chan] = i2c_add_mux_adapter(adap, &dump_dev, NULL, 0,
chan,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
0,
#endif
delta_i2c_cpld_mux_select_chan,
delta_i2c_cpld_mux_deselect_mux);
if (cpld_mux_data->virt_adaps[chan] == NULL) {
ret = -ENODEV;
printk("failed to register multiplexed adapter %d, parent %d\n", chan, PARENT_CHAN);
goto virt_reg_failed;
}
}
printk("registered %d multiplexed busses for I2C mux bus %d\n",
chan, PARENT_CHAN);
return 0;
virt_reg_failed:
for (chan--; chan >= 0; chan--) {
i2c_del_mux_adapter(cpld_mux_data->virt_adaps[chan]);
}
kfree(cpld_mux_data);
err:
return ret;
}
static int __delta_i2c_cpld_mux_remove(void)
{
const struct chip_desc *chip = &chips[cpld_mux_data->type];
int chan;
for (chan = 0; chan < chip->nchans; ++chan) {
if (cpld_mux_data->virt_adaps[chan]) {
i2c_del_mux_adapter(cpld_mux_data->virt_adaps[chan]);
cpld_mux_data->virt_adaps[chan] = NULL;
}
}
kfree(cpld_mux_data);
return 0;
}
static int __init delta_i2c_cpld_mux_init(void)
{
return __delta_i2c_cpld_mux_init ();
}
static void __exit delta_i2c_cpld_mux_exit(void)
{
__delta_i2c_cpld_mux_remove ();
}
MODULE_AUTHOR("Dave Hu <dave.hu@deltasystems.com>");
MODULE_DESCRIPTION("Delta I2C CPLD mux driver");
MODULE_LICENSE("GPL");
module_init(delta_i2c_cpld_mux_init);
module_exit(delta_i2c_cpld_mux_exit);

View File

@@ -0,0 +1,317 @@
/*
* An I2C multiplexer dirver for delta ag7648 CPLD
*
* Copyright (C) 2015 Delta Technology Corporation.
* Brandon Chuang <brandon_chuang@delta.com.tw>
*
* This module supports the delta cpld that hold the channel select
* mechanism for other i2c slave devices, such as SFP.
* This includes the:
* Delta ag7648c CPLD1/CPLD2/CPLD3
*
* Based on:
* pca954x.c from Kumar Gala <galak@kernel.crashing.org>
* Copyright (C) 2006
*
* Based on:
* pca954x.c from Ken Harrenstien
* Copyright (C) 2004 Google, Inc. (Ken Harrenstien)
*
* Based on:
* i2c-virtual_cb.c from Brian Kuschak <bkuschak@yahoo.com>
* and
* pca9540.c from Jean Delvare <khali@linux-fr.org>.
*
* 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.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/version.h>
#include <linux/delay.h>
#define CTRL_CPLD_BUS 0x2
#define CTRL_CPLD_I2C_ADDR 0x32
#define PARENT_CHAN 0x5
#define NUM_OF_CPLD_CHANS 0x6
#define CPLD_CHANNEL_SELECT_REG 0xa
#define CPLD_CHANNEL_SELECT_MASK 0x3f
#define CPLD_CHANNEL_SELECT_OFFSET 0x0
#define CPLD_QSFP_INTR_STATUS_REG 0xe
#define CPLD_QSFP_INTR_STATUS_OFFSET 0x0
#define CPLD_QSFP_RESET_CTRL_REG 0xd
#define CPLD_QSFL_RESET_CTRL_OFFSET 0x0
#define CPLD_DESELECT_CHANNEL 0xff
#define CPLD_MUX_MAX_NCHANS 0x6
enum cpld_mux_type {
delta_cpld_mux
};
struct delta_i2c_cpld_mux {
enum cpld_mux_type type;
struct i2c_adapter *virt_adaps[CPLD_MUX_MAX_NCHANS];
u8 last_chan; /* last register value */
};
struct chip_desc {
u8 nchans;
u8 deselectChan;
};
/* Provide specs for the PCA954x types we know about */
static const struct chip_desc chips[] = {
[delta_cpld_mux] = {
.nchans = NUM_OF_CPLD_CHANS,
.deselectChan = CPLD_DESELECT_CHANNEL,
}
};
static struct delta_i2c_cpld_mux *cpld_mux_data;
static struct device dump_dev;
/* 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 delta_i2c_cpld_mux_reg_write(struct i2c_adapter *adap,
struct i2c_client *client, u8 val)
{
unsigned long orig_jiffies;
unsigned short flags;
union i2c_smbus_data data;
struct i2c_adapter *ctrl_adap;
int try,change=0;
s32 res = -EIO;
u8 reg_val = 0;
int intr, reset_ctrl;
int i;
data.byte = val;
flags = 0;
ctrl_adap = i2c_get_adapter(CTRL_CPLD_BUS);
if (!ctrl_adap)
return res;
// try to lock it
if (ctrl_adap->algo->smbus_xfer) {
/* Retry automatically on arbitration loss */
orig_jiffies = jiffies;
for (res = 0, try = 0; try <= ctrl_adap->retries; try++) {
// workaround
data.byte = 0;
res = ctrl_adap->algo->smbus_xfer(ctrl_adap, CTRL_CPLD_I2C_ADDR, flags,
I2C_SMBUS_WRITE, CPLD_CHANNEL_SELECT_REG,
I2C_SMBUS_BYTE_DATA, &data);
if (res == -EAGAIN)
continue;
//read the interrupt status
res = ctrl_adap->algo->smbus_xfer(ctrl_adap, CTRL_CPLD_I2C_ADDR, flags,
I2C_SMBUS_READ, CPLD_QSFP_INTR_STATUS_REG,
I2C_SMBUS_BYTE_DATA, &data);
if ( res == -EAGAIN)
continue;
intr = data.byte;
//read the reset control
res = ctrl_adap->algo->smbus_xfer(ctrl_adap, CTRL_CPLD_I2C_ADDR, flags,
I2C_SMBUS_READ, CPLD_QSFP_RESET_CTRL_REG,
I2C_SMBUS_BYTE_DATA, &data);
if ( res == -EAGAIN)
continue;
reset_ctrl = data.byte;
/* there is an interrupt for QSFP port, including failure/plugin/un-plugin
* try to reset it.
*
*/
for (i = 0 ; i < NUM_OF_CPLD_CHANS; i ++)
{
if((reset_ctrl & ( 1 << i )) == 0){
change=1;
}
if ((intr & ( 1 << i )) == 0 )
{
res = ctrl_adap->algo->smbus_xfer(ctrl_adap, CTRL_CPLD_I2C_ADDR, flags,
I2C_SMBUS_READ, CPLD_QSFP_RESET_CTRL_REG,
I2C_SMBUS_BYTE_DATA, &data);
if (res == -EAGAIN)
continue;
data.byte &= ~(1 << i);
res = ctrl_adap->algo->smbus_xfer(ctrl_adap, CTRL_CPLD_I2C_ADDR, flags,
I2C_SMBUS_WRITE, CPLD_QSFP_RESET_CTRL_REG,
I2C_SMBUS_BYTE_DATA, &data);
if (res == -EAGAIN)
continue;
change=1;
}
}
if(change){
msleep(10);
data.byte=CPLD_DESELECT_CHANNEL;
res = ctrl_adap->algo->smbus_xfer(ctrl_adap, CTRL_CPLD_I2C_ADDR, flags,
I2C_SMBUS_WRITE, CPLD_QSFP_RESET_CTRL_REG,
I2C_SMBUS_BYTE_DATA, &data);
if (res == -EAGAIN)
continue;
msleep(200);
}
// read first
//res = ctrl_adap->algo->smbus_xfer(ctrl_adap, CTRL_CPLD_I2C_ADDR, flags,
// I2C_SMBUS_READ, CPLD_CHANNEL_SELECT_REG,
// I2C_SMBUS_BYTE_DATA, &data);
//if (res && res != -EAGAIN)
// break;
// modify the field we wanted
//data.byte &= ~(CPLD_CHANNEL_SELECT_MASK << CPLD_CHANNEL_SELECT_OFFSET);
//reg_val |= (((~(1 << val)) & CPLD_CHANNEL_SELECT_MASK) << CPLD_CHANNEL_SELECT_OFFSET);
data.byte = (~(1 << val)) & 0xff;
// modify the register
res = ctrl_adap->algo->smbus_xfer(ctrl_adap, CTRL_CPLD_I2C_ADDR, flags,
I2C_SMBUS_WRITE, CPLD_CHANNEL_SELECT_REG,
I2C_SMBUS_BYTE_DATA, &data);
if (res != -EAGAIN)
break;
if (time_after(jiffies,
orig_jiffies + ctrl_adap->timeout))
break;
}
}
return res;
}
static int delta_i2c_cpld_mux_select_chan(struct i2c_adapter *adap,
void *client, u32 chan)
{
u8 regval;
int ret = 0;
regval = chan;
/* Only select the channel if its different from the last channel */
if (cpld_mux_data->last_chan != regval) {
ret = delta_i2c_cpld_mux_reg_write(NULL, NULL, regval);
cpld_mux_data->last_chan = regval;
}
return ret;
}
static int delta_i2c_cpld_mux_deselect_mux(struct i2c_adapter *adap,
void *client, u32 chan)
{
/* Deselect active channel */
cpld_mux_data->last_chan = chips[cpld_mux_data->type].deselectChan;
return delta_i2c_cpld_mux_reg_write(NULL, NULL, cpld_mux_data->last_chan);
}
/*
* I2C init/probing/exit functions
*/
static int __delta_i2c_cpld_mux_init(void)
{
struct i2c_adapter *adap = i2c_get_adapter(PARENT_CHAN);
int chan=0;
int ret = -ENODEV;
memset (&dump_dev, 0, sizeof(dump_dev));
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
goto err;
if (!adap)
goto err;
cpld_mux_data = kzalloc(sizeof(struct delta_i2c_cpld_mux), GFP_KERNEL);
if (!cpld_mux_data) {
ret = -ENOMEM;
goto err;
}
cpld_mux_data->type = delta_cpld_mux;
cpld_mux_data->last_chan = chips[cpld_mux_data->type].deselectChan; /* force the first selection */
/* Now create an adapter for each channel */
for (chan = 0; chan < NUM_OF_CPLD_CHANS; chan++) {
cpld_mux_data->virt_adaps[chan] = i2c_add_mux_adapter(adap, &dump_dev, NULL, 0,
chan,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
0,
#endif
delta_i2c_cpld_mux_select_chan,
delta_i2c_cpld_mux_deselect_mux);
if (cpld_mux_data->virt_adaps[chan] == NULL) {
ret = -ENODEV;
printk("failed to register multiplexed adapter %d, parent %d\n", chan, PARENT_CHAN);
goto virt_reg_failed;
}
}
printk("registered %d multiplexed busses for I2C mux bus %d\n",
chan, PARENT_CHAN);
return 0;
virt_reg_failed:
for (chan--; chan >= 0; chan--) {
i2c_del_mux_adapter(cpld_mux_data->virt_adaps[chan]);
}
kfree(cpld_mux_data);
err:
return ret;
}
static int __delta_i2c_cpld_mux_remove(void)
{
const struct chip_desc *chip = &chips[cpld_mux_data->type];
int chan;
for (chan = 0; chan < chip->nchans; ++chan) {
if (cpld_mux_data->virt_adaps[chan]) {
i2c_del_mux_adapter(cpld_mux_data->virt_adaps[chan]);
cpld_mux_data->virt_adaps[chan] = NULL;
}
}
kfree(cpld_mux_data);
return 0;
}
static int __init delta_i2c_cpld_mux_init(void)
{
return __delta_i2c_cpld_mux_init ();
}
static void __exit delta_i2c_cpld_mux_exit(void)
{
__delta_i2c_cpld_mux_remove ();
}
MODULE_AUTHOR("Dave Hu <dave.hu@deltasystems.com>");
MODULE_DESCRIPTION("Delta I2C CPLD mux driver");
MODULE_LICENSE("GPL");
module_init(delta_i2c_cpld_mux_init);
module_exit(delta_i2c_cpld_mux_exit);

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
!include $ONL_TEMPLATES/onlp-platform-any.yml PLATFORM=x86-64-delta-ag7648 ARCH=amd64 TOOLCHAIN=x86_64-linux-gnu

View File

@@ -0,0 +1,2 @@
FILTER=src
include $(ONL)/make/subdirs.mk

View File

@@ -0,0 +1,45 @@
############################################################
# <bsn.cl fy=2014 v=onl>
#
# Copyright 2014 BigSwitch Networks, Inc.
#
# Licensed under the Eclipse Public License, Version 1.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.eclipse.org/legal/epl-v10.html
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the License for the specific
# language governing permissions and limitations under the
# License.
#
# </bsn.cl>
############################################################
#
#
############################################################
include $(ONL)/make/config.amd64.mk
MODULE := libonlp-x86-64-delta-ag7648
include $(BUILDER)/standardinit.mk
DEPENDMODULES := AIM IOF x86_64_delta_ag7648 onlplib
DEPENDMODULE_HEADERS := sff
include $(BUILDER)/dependmodules.mk
SHAREDLIB := libonlp-x86-64-delta-ag7648.so
$(SHAREDLIB)_TARGETS := $(ALL_TARGETS)
include $(BUILDER)/so.mk
.DEFAULT_GOAL := $(SHAREDLIB)
GLOBAL_CFLAGS += -I$(onlp_BASEDIR)/module/inc
GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MODULES_INIT=1
GLOBAL_CFLAGS += -fPIC
GLOBAL_LINK_LIBS += -lpthread
include $(BUILDER)/targets.mk

View File

@@ -0,0 +1,10 @@
###############################################################################
#
# Inclusive Makefile for the libonlp-x86-64-delta-ag7648 module.
#
# Autogenerated 2017-03-20 15:05:28.120004
#
###############################################################################
libonlp-x86-64-delta-ag7648_BASEDIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

View File

@@ -0,0 +1,46 @@
############################################################
# <bsn.cl fy=2014 v=onl>
#
# Copyright 2014 BigSwitch Networks, Inc.
#
# Licensed under the Eclipse Public License, Version 1.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.eclipse.org/legal/epl-v10.html
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the License for the specific
# language governing permissions and limitations under the
# License.
#
# </bsn.cl>
############################################################
#
#
#
############################################################
include $(ONL)/make/config.amd64.mk
.DEFAULT_GOAL := onlpdump
MODULE := onlpdump
include $(BUILDER)/standardinit.mk
DEPENDMODULES := AIM IOF onlp x86_64_delta_ag7648 onlplib onlp_platform_defaults sff cjson cjson_util timer_wheel OS
include $(BUILDER)/dependmodules.mk
BINARY := onlpdump
$(BINARY)_LIBRARIES := $(LIBRARY_TARGETS)
include $(BUILDER)/bin.mk
GLOBAL_CFLAGS += -DAIM_CONFIG_AIM_MAIN_FUNCTION=onlpdump_main
GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MODULES_INIT=1
GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MAIN=1
GLOBAL_LINK_LIBS += -lpthread -lm
include $(BUILDER)/targets.mk

View File

@@ -0,0 +1 @@
name: x86_64_delta_ag7648

View File

@@ -0,0 +1,9 @@
###############################################################################
#
#
#
###############################################################################
include ../../init.mk
MODULE := x86_64_delta_ag7648
AUTOMODULE := x86_64_delta_ag7648
include $(BUILDER)/definemodule.mk

View File

@@ -0,0 +1,6 @@
###############################################################################
#
# x86_64_delta_ag7648 README
#
###############################################################################

View File

@@ -0,0 +1,9 @@
###############################################################################
#
# x86_64_delta_ag7648 Autogeneration
#
###############################################################################
x86_64_delta_ag7648_AUTO_DEFS := module/auto/x86_64_delta_ag7648.yml
x86_64_delta_ag7648_AUTO_DIRS := module/inc/x86_64_delta_ag7648 module/src
include $(BUILDER)/auto.mk

View File

@@ -0,0 +1,50 @@
###############################################################################
#
# x86_64_delta_ag7648 Autogeneration Definitions.
#
###############################################################################
cdefs: &cdefs
- X86_64_DELTA_AG7648_CONFIG_INCLUDE_LOGGING:
doc: "Include or exclude logging."
default: 1
- X86_64_DELTA_AG7648_CONFIG_LOG_OPTIONS_DEFAULT:
doc: "Default enabled log options."
default: AIM_LOG_OPTIONS_DEFAULT
- X86_64_DELTA_AG7648_CONFIG_LOG_BITS_DEFAULT:
doc: "Default enabled log bits."
default: AIM_LOG_BITS_DEFAULT
- X86_64_DELTA_AG7648_CONFIG_LOG_CUSTOM_BITS_DEFAULT:
doc: "Default enabled custom log bits."
default: 0
- X86_64_DELTA_AG7648_CONFIG_PORTING_STDLIB:
doc: "Default all porting macros to use the C standard libraries."
default: 1
- X86_64_DELTA_AG7648_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS:
doc: "Include standard library headers for stdlib porting macros."
default: X86_64_DELTA_AG7648_CONFIG_PORTING_STDLIB
- X86_64_DELTA_AG7648_CONFIG_INCLUDE_UCLI:
doc: "Include generic uCli support."
default: 0
- X86_64_DELTA_AG7648_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION:
doc: "Assume chassis fan direction is the same as the PSU fan direction."
default: 0
definitions:
cdefs:
X86_64_DELTA_AG7648_CONFIG_HEADER:
defs: *cdefs
basename: x86_64_delta_ag7648_config
portingmacro:
x86_64_delta_ag7648:
macros:
- malloc
- free
- memset
- memcpy
- strncpy
- vsnprintf
- snprintf
- strlen

View File

@@ -0,0 +1,14 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_delta_ag7648/x86_64_delta_ag7648_config.h>
/* <--auto.start.xmacro(ALL).define> */
/* <auto.end.xmacro(ALL).define> */
/* <--auto.start.xenum(ALL).define> */
/* <auto.end.xenum(ALL).define> */

View File

@@ -0,0 +1,137 @@
/**************************************************************************//**
*
* @file
* @brief x86_64_delta_ag7648 Configuration Header
*
* @addtogroup x86_64_delta_ag7648-config
* @{
*
*****************************************************************************/
#ifndef __X86_64_DELTA_AG7648_CONFIG_H__
#define __X86_64_DELTA_AG7648_CONFIG_H__
#ifdef GLOBAL_INCLUDE_CUSTOM_CONFIG
#include <global_custom_config.h>
#endif
#ifdef X86_64_DELTA_AG7648_INCLUDE_CUSTOM_CONFIG
#include <x86_64_delta_ag7648_custom_config.h>
#endif
/* <auto.start.cdefs(X86_64_DELTA_AG7648_CONFIG_HEADER).header> */
#include <AIM/aim.h>
/**
* X86_64_DELTA_AG7648_CONFIG_INCLUDE_LOGGING
*
* Include or exclude logging. */
#ifndef X86_64_DELTA_AG7648_CONFIG_INCLUDE_LOGGING
#define X86_64_DELTA_AG7648_CONFIG_INCLUDE_LOGGING 1
#endif
/**
* X86_64_DELTA_AG7648_CONFIG_LOG_OPTIONS_DEFAULT
*
* Default enabled log options. */
#ifndef X86_64_DELTA_AG7648_CONFIG_LOG_OPTIONS_DEFAULT
#define X86_64_DELTA_AG7648_CONFIG_LOG_OPTIONS_DEFAULT AIM_LOG_OPTIONS_DEFAULT
#endif
/**
* X86_64_DELTA_AG7648_CONFIG_LOG_BITS_DEFAULT
*
* Default enabled log bits. */
#ifndef X86_64_DELTA_AG7648_CONFIG_LOG_BITS_DEFAULT
#define X86_64_DELTA_AG7648_CONFIG_LOG_BITS_DEFAULT AIM_LOG_BITS_DEFAULT
#endif
/**
* X86_64_DELTA_AG7648_CONFIG_LOG_CUSTOM_BITS_DEFAULT
*
* Default enabled custom log bits. */
#ifndef X86_64_DELTA_AG7648_CONFIG_LOG_CUSTOM_BITS_DEFAULT
#define X86_64_DELTA_AG7648_CONFIG_LOG_CUSTOM_BITS_DEFAULT 0
#endif
/**
* X86_64_DELTA_AG7648_CONFIG_PORTING_STDLIB
*
* Default all porting macros to use the C standard libraries. */
#ifndef X86_64_DELTA_AG7648_CONFIG_PORTING_STDLIB
#define X86_64_DELTA_AG7648_CONFIG_PORTING_STDLIB 1
#endif
/**
* X86_64_DELTA_AG7648_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS
*
* Include standard library headers for stdlib porting macros. */
#ifndef X86_64_DELTA_AG7648_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS
#define X86_64_DELTA_AG7648_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS X86_64_DELTA_AG7648_CONFIG_PORTING_STDLIB
#endif
/**
* X86_64_DELTA_AG7648_CONFIG_INCLUDE_UCLI
*
* Include generic uCli support. */
#ifndef X86_64_DELTA_AG7648_CONFIG_INCLUDE_UCLI
#define X86_64_DELTA_AG7648_CONFIG_INCLUDE_UCLI 0
#endif
/**
* X86_64_DELTA_AG7648_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION
*
* Assume chassis fan direction is the same as the PSU fan direction. */
#ifndef X86_64_DELTA_AG7648_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION
#define X86_64_DELTA_AG7648_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION 0
#endif
/**
* All compile time options can be queried or displayed
*/
/** Configuration settings structure. */
typedef struct x86_64_delta_ag7648_config_settings_s {
/** name */
const char* name;
/** value */
const char* value;
} x86_64_delta_ag7648_config_settings_t;
/** Configuration settings table. */
/** x86_64_delta_ag7648_config_settings table. */
extern x86_64_delta_ag7648_config_settings_t x86_64_delta_ag7648_config_settings[];
/**
* @brief Lookup a configuration setting.
* @param setting The name of the configuration option to lookup.
*/
const char* x86_64_delta_ag7648_config_lookup(const char* setting);
/**
* @brief Show the compile-time configuration.
* @param pvs The output stream.
*/
int x86_64_delta_ag7648_config_show(struct aim_pvs_s* pvs);
/* <auto.end.cdefs(X86_64_DELTA_AG7648_CONFIG_HEADER).header> */
#include "x86_64_delta_ag7648_porting.h"
#endif /* __X86_64_DELTA_AG7648_CONFIG_H__ */
/* @} */

View File

@@ -0,0 +1,26 @@
/**************************************************************************//**
*
* x86_64_delta_ag7648 Doxygen Header
*
*****************************************************************************/
#ifndef __X86_64_DELTA_AG7648_DOX_H__
#define __X86_64_DELTA_AG7648_DOX_H__
/**
* @defgroup x86_64_delta_ag7648 x86_64_delta_ag7648 - x86_64_delta_ag7648 Description
*
The documentation overview for this module should go here.
*
* @{
*
* @defgroup x86_64_delta_ag7648-x86_64_delta_ag7648 Public Interface
* @defgroup x86_64_delta_ag7648-config Compile Time Configuration
* @defgroup x86_64_delta_ag7648-porting Porting Macros
*
* @}
*
*/
#endif /* __X86_64_DELTA_AG7648_DOX_H__ */

View File

@@ -0,0 +1,107 @@
/**************************************************************************//**
*
* @file
* @brief x86_64_delta_ag7648 Porting Macros.
*
* @addtogroup x86_64_delta_ag7648-porting
* @{
*
*****************************************************************************/
#ifndef __X86_64_DELTA_AG7648_PORTING_H__
#define __X86_64_DELTA_AG7648_PORTING_H__
/* <auto.start.portingmacro(ALL).define> */
#if X86_64_DELTA_AG7648_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS == 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <memory.h>
#endif
#ifndef x86_64_delta_ag7648_MALLOC
#if defined(GLOBAL_MALLOC)
#define x86_64_delta_ag7648_MALLOC GLOBAL_MALLOC
#elif X86_64_DELTA_AG7648_CONFIG_PORTING_STDLIB == 1
#define x86_64_delta_ag7648_MALLOC malloc
#else
#error The macro x86_64_delta_ag7648_MALLOC is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_ag7648_FREE
#if defined(GLOBAL_FREE)
#define x86_64_delta_ag7648_FREE GLOBAL_FREE
#elif X86_64_DELTA_AG7648_CONFIG_PORTING_STDLIB == 1
#define x86_64_delta_ag7648_FREE free
#else
#error The macro x86_64_delta_ag7648_FREE is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_ag7648_MEMSET
#if defined(GLOBAL_MEMSET)
#define x86_64_delta_ag7648_MEMSET GLOBAL_MEMSET
#elif X86_64_DELTA_AG7648_CONFIG_PORTING_STDLIB == 1
#define x86_64_delta_ag7648_MEMSET memset
#else
#error The macro x86_64_delta_ag7648_MEMSET is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_ag7648_MEMCPY
#if defined(GLOBAL_MEMCPY)
#define x86_64_delta_ag7648_MEMCPY GLOBAL_MEMCPY
#elif X86_64_DELTA_AG7648_CONFIG_PORTING_STDLIB == 1
#define x86_64_delta_ag7648_MEMCPY memcpy
#else
#error The macro x86_64_delta_ag7648_MEMCPY is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_ag7648_STRNCPY
#if defined(GLOBAL_STRNCPY)
#define x86_64_delta_ag7648_STRNCPY GLOBAL_STRNCPY
#elif X86_64_DELTA_AG7648_CONFIG_PORTING_STDLIB == 1
#define x86_64_delta_ag7648_STRNCPY strncpy
#else
#error The macro x86_64_delta_ag7648_STRNCPY is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_ag7648_VSNPRINTF
#if defined(GLOBAL_VSNPRINTF)
#define x86_64_delta_ag7648_VSNPRINTF GLOBAL_VSNPRINTF
#elif X86_64_DELTA_AG7648_CONFIG_PORTING_STDLIB == 1
#define x86_64_delta_ag7648_VSNPRINTF vsnprintf
#else
#error The macro x86_64_delta_ag7648_VSNPRINTF is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_ag7648_SNPRINTF
#if defined(GLOBAL_SNPRINTF)
#define x86_64_delta_ag7648_SNPRINTF GLOBAL_SNPRINTF
#elif X86_64_DELTA_AG7648_CONFIG_PORTING_STDLIB == 1
#define x86_64_delta_ag7648_SNPRINTF snprintf
#else
#error The macro x86_64_delta_ag7648_SNPRINTF is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_ag7648_STRLEN
#if defined(GLOBAL_STRLEN)
#define x86_64_delta_ag7648_STRLEN GLOBAL_STRLEN
#elif X86_64_DELTA_AG7648_CONFIG_PORTING_STDLIB == 1
#define x86_64_delta_ag7648_STRLEN strlen
#else
#error The macro x86_64_delta_ag7648_STRLEN is required but cannot be defined.
#endif
#endif
/* <auto.end.portingmacro(ALL).define> */
#endif /* __X86_64_DELTA_AG7648_PORTING_H__ */
/* @} */

View File

@@ -0,0 +1,10 @@
###############################################################################
#
#
#
###############################################################################
THIS_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
x86_64_delta_ag7648_INCLUDES := -I $(THIS_DIR)inc
x86_64_delta_ag7648_INTERNAL_INCLUDES := -I $(THIS_DIR)src
x86_64_delta_ag7648_DEPENDMODULE_ENTRIES := init:x86_64_delta_ag7648 ucli:x86_64_delta_ag7648

View File

@@ -0,0 +1,9 @@
###############################################################################
#
# Local source generation targets.
#
###############################################################################
ucli:
@../../../../tools/uclihandlers.py x86_64_delta_ag7648_ucli.c

View File

@@ -0,0 +1,45 @@
#include "x86_64_delta_ag7648_int.h"
#if X86_64_DELTA_AG7648_CONFIG_INCLUDE_DEBUG == 1
#include <unistd.h>
static char help__[] =
"Usage: debug [options]\n"
" -c CPLD Versions\n"
" -h Help\n"
;
int
x86_64_delta_ag7648_debug_main(int argc, char* argv[])
{
int c = 0;
int help = 0;
int rv = 0;
while( (c = getopt(argc, argv, "ch")) != -1) {
switch(c)
{
case 'c': c = 1; break;
case 'h': help = 1; rv = 0; break;
default: help = 1; rv = 1; break;
}
}
if(help || argc == 1) {
printf("%s", help__);
return rv;
}
if(c) {
printf("Not implemented.\n");
}
return 0;
}
#endif

View File

@@ -0,0 +1,593 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014, 2015 Big Switch Networks, Inc.
* Copyright 2016 Accton Technology Corporation.
* Copyright 2017 Delta Networks, Inc
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
* Fan Platform Implementation Defaults.
*
***********************************************************/
#include <onlp/platformi/fani.h>
#include <unistd.h>
#include <fcntl.h>
#include "platform_lib.h"
#include "x86_64_delta_ag7648_int.h"
#include "x86_64_delta_i2c.h"
#define MAX_FAN_SPEED 19000
#define MAX_PSU1_FAN_SPEED 19000
#define MAX_PSU2_FAN_SPEED 18000
#define FILE_NAME_LEN 80
#define CPLD_FAN_NAME "MASTERCPLD"
#define CPLD_FAN_TRAY0_PRESENT_REG (0x8)
#define CPLD_FAN_TRAY0_PRESENT_REG_OFFSET (0x6)
#define CPLD_FAN_TRAY1_PRESENT_REG (0x8)
#define CPLD_FAN_TRAY1_PRESENT_REG_OFFSET (0x7)
#define CPLD_FAN_TRAY2_PRESENT_REG (0x9)
#define CPLD_FAN_TRAY2_PRESENT_REG_OFFSET (0x0)
/* The MAX6620 registers, valid channel numbers: 0, 1 */
#define MAX6639_REG_STATUS 0x02
#define MAX6639_REG_FAN_CONFIG1(ch) (0x10 + 4*(ch-1))
#define MAX6639_REG_FAN_CNT(ch) (0x20 + (ch-1))
#define MAX6639_REG_TARGET_CNT(ch) (0x22 + (ch-1))
/*define the reg bit mask*/
#define MAX6639_REG_FAN_STATUS_BIT(ch) (0X02>>(ch-1))
#define MAX6639_FAN_CONFIG1_RPM_RANGE 0x03
#define MAX6639_FAN_PRESENT_REG (0x0c)
#define MAX6639_FAN_PRESENT_BIT (0x2)
#define MAX6639_FAN_GOOD_BIT (0x1)
#define FAN_FROM_REG(d1, d2) \
{ \
int tech = (d1 << 3) | ((d2 >> 5) & 0x07);\
rpm = (491520 * 4) / (2 * tech);\
}
#define FAN_TO_REG(rpm) \
{ \
float ftech; \
uint32_t tech; \
ftech = (491520.0 * 4)/ (2.0 * rpm); \
ftech = ftech + 0.3; \
tech = (uint32_t) ftech; \
d1 = (uint8_t)(tech >> 3); \
d2 = (uint8_t)((tech << 5) & 0xe0);\
}
static int fan_initd=0;
enum onlp_fan_id
{
FAN_RESERVED = 0,
FAN_1_ON_MAIN_BOARD, /*fan tray 0*/
FAN_2_ON_MAIN_BOARD, /*fan tray 0*/
FAN_3_ON_MAIN_BOARD, /*fan tray 1*/
FAN_4_ON_MAIN_BOARD, /*fan tray 1*/
FAN_5_ON_MAIN_BOARD, /*fan tray 2*/
FAN_6_ON_MAIN_BOARD, /*fan tray 2*/
FAN_1_ON_PSU1,
FAN_1_ON_PSU2
};
enum onlp_fan_tray_id
{
FAN_TRAY_0 = 0,
FAN_TRAY_1 = 1,
FAN_TRAY_2 = 2
};
#define MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(id) \
{ \
{ ONLP_FAN_ID_CREATE(FAN_##id##_ON_MAIN_BOARD), "Chassis Fan "#id, 0 }, \
ONLP_FAN_STATUS_B2F | ONLP_FAN_STATUS_PRESENT, \
(ONLP_FAN_CAPS_SET_PERCENTAGE |ONLP_FAN_CAPS_SET_RPM| ONLP_FAN_CAPS_GET_RPM | ONLP_FAN_CAPS_GET_PERCENTAGE), \
0, \
0, \
ONLP_FAN_MODE_INVALID, \
}
#define MAKE_FAN_INFO_NODE_ON_PSU(psu_id, fan_id) \
{ \
{ ONLP_FAN_ID_CREATE(FAN_##fan_id##_ON_PSU##psu_id), "Chassis PSU-"#psu_id " Fan "#fan_id, 0 }, \
ONLP_FAN_STATUS_B2F | ONLP_FAN_STATUS_PRESENT, \
(ONLP_FAN_CAPS_GET_RPM | ONLP_FAN_CAPS_GET_PERCENTAGE), \
0, \
0, \
ONLP_FAN_MODE_INVALID, \
}
/* Static fan information */
onlp_fan_info_t linfo[] = {
{ }, /* Not used */
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(1),
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(2),
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(3),
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(4),
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(5),
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(6),
MAKE_FAN_INFO_NODE_ON_PSU(1,1),
MAKE_FAN_INFO_NODE_ON_PSU(2,1),
};
#define VALIDATE(_id) \
do { \
if(!ONLP_OID_IS_FAN(_id)) { \
return ONLP_STATUS_E_INVALID; \
} \
} while(0)
static int
_onlp_get_fan_tray(int fanId)
{
int tray_id;
if((fanId==5) || (fanId==6))
tray_id=0;
else if((fanId==3) || (fanId==4))
tray_id=1;
else
tray_id=2;
return tray_id;
}
#if 0
static int
_onlp_psu_fan_val_to_rpm (int v)
{
int lf = (v & 0xffff);
int y, n;
y = lf & 0x7ff;
n = ((lf >> 11) & 0x1f);
return (y * (1 << n));
}
#endif
static int
_onlp_fan_board_init(void)
{
int i = 0;
int d1,d2;
int rpm = 8000;
i2c_devname_write_byte("FANCTRL1", 0x00,0x10);
i2c_devname_write_byte("FANCTRL2", 0x00,0x10);
i2c_devname_write_byte("FANCTRL1", 0x01,0x00);
i2c_devname_write_byte("FANCTRL2", 0x01,0x00);
for (i = FAN_1_ON_MAIN_BOARD; i <= FAN_4_ON_MAIN_BOARD; i ++)
{
int offset = i - FAN_1_ON_MAIN_BOARD;
i2c_devname_write_byte("FANCTRL2", 0x02 + offset ,0xc0);
FAN_TO_REG(rpm);
i2c_devname_write_byte("FANCTRL2", 0x20 + 2 * offset, d1);
i2c_devname_write_byte("FANCTRL2", 0x21 + 2 * offset, d2);
}
for (i = FAN_5_ON_MAIN_BOARD; i <= FAN_6_ON_MAIN_BOARD; i ++)
{
int offset = i - FAN_5_ON_MAIN_BOARD;
i2c_devname_write_byte("FANCTRL1", 0x02 + offset ,0xc0);
FAN_TO_REG(rpm);
i2c_devname_write_byte("FANCTRL1", 0x20 + 2 * offset, d1);
i2c_devname_write_byte("FANCTRL1", 0x21 + 2 * offset, d2);
}
fan_initd=1;
return ONLP_STATUS_OK;
}
static int
_onlp_fani_info_get_fan(int local_id, onlp_fan_info_t* info)
{
int r_data, fan_present;
int fan_tray = 0;
int reg, offset;
int d1, d2;
int rpm;
/* init the fan on the board*/
if(fan_initd==0)
_onlp_fan_board_init();
fan_tray = _onlp_get_fan_tray(local_id);
if (fan_tray == 0)
{
reg = CPLD_FAN_TRAY0_PRESENT_REG;
offset = CPLD_FAN_TRAY0_PRESENT_REG_OFFSET;
}else if (fan_tray == 1)
{
reg = CPLD_FAN_TRAY1_PRESENT_REG;
offset = CPLD_FAN_TRAY1_PRESENT_REG_OFFSET;
}else if (fan_tray == 2)
{
reg = CPLD_FAN_TRAY2_PRESENT_REG;
offset = CPLD_FAN_TRAY2_PRESENT_REG_OFFSET;
}else
{
return ONLP_STATUS_E_INVALID;
}
/* get fan fault status (turn on when any one fails)*/
r_data = i2c_devname_read_byte(CPLD_FAN_NAME, reg);
if(r_data<0)
return ONLP_STATUS_E_INVALID;
fan_present = (r_data >> offset ) & 0x1;
if(!fan_present){
info->status |= ONLP_FAN_STATUS_PRESENT;
if (fan_tray == 0)
{
d1 = i2c_devname_read_byte("FANCTRL1", 0x10 + 2 * (local_id - FAN_5_ON_MAIN_BOARD));
d2 = i2c_devname_read_byte("FANCTRL1", 0x11 + 2 * (local_id - FAN_5_ON_MAIN_BOARD));
}else
{
d1 = i2c_devname_read_byte("FANCTRL2", 0x10 + 2 * (local_id - FAN_1_ON_MAIN_BOARD) );
d2 = i2c_devname_read_byte("FANCTRL2", 0x11 + 2 * (local_id - FAN_1_ON_MAIN_BOARD) );
}
if (d1 < 0 || d2 < 0)
{
info->status |= ONLP_FAN_STATUS_FAILED;
return ONLP_STATUS_E_INVALID;
}
}
else{
info->status &= ~ONLP_FAN_STATUS_PRESENT;
return ONLP_STATUS_E_UNSUPPORTED;
}
DEBUG_PRINT("d1 %d, d2 %d\r\n", d1, d2);
FAN_FROM_REG(d1,d2);
info->rpm = rpm;
DEBUG_PRINT("rpm %d\r\n", rpm);
/* get speed percentage from rpm */
info->percentage = (info->rpm * 100.0) / MAX_FAN_SPEED;
if(info->percentage>100)
strcpy(info->model,"ONLP_FAN_MODE_LAST");
else if(info->percentage==100)
strcpy(info->model,"ONLP_FAN_MODE_MAX");
else if(info->percentage>=75&&info->percentage<100)
strcpy(info->model,"ONLP_FAN_MODE_FAST");
else if(info->percentage>=35&&info->percentage<75)
strcpy(info->model,"ONLP_FAN_MODE_NORMAL");
else if(info->percentage>0&&info->percentage<35)
strcpy(info->model,"ONLP_FAN_MODE_SLOW");
else if(info->percentage<=0)
strcpy(info->model,"ONLP_FAN_MODE_OFF");
else{ }
return ONLP_STATUS_OK;
}
static int
_onlp_fani_info_get_fan_on_psu(int local_id, onlp_fan_info_t* info)
{
#if 0
int psu_id;
int r_data,fan_rpm;
psu_type_t psu_type;
/* get fan fault status
*/
psu_id = (local_id - FAN_1_ON_PSU1) + 1;
DEBUG_PRINT("[Debug][%s][%d][psu_id: %d]\n", __FUNCTION__, __LINE__, psu_id);
psu_type = get_psu_type(psu_id); /* psu_id = 1 , present PSU1. pus_id =2 , present PSU2 */
DEBUG_PRINT("[Debug][%s][%d][psu_type: %d]\n", __FUNCTION__, __LINE__, psu_type);
switch (psu_type) {
case PSU_TYPE_AC_F2B:
info->status |= (ONLP_FAN_STATUS_PRESENT | ONLP_FAN_STATUS_F2B);
break;
case PSU_TYPE_AC_B2F:
info->status |= (ONLP_FAN_STATUS_PRESENT | ONLP_FAN_STATUS_B2F);
break;
default:
return ONLP_STATUS_E_UNSUPPORTED;
}
/* get fan speed*/
if(pid == PID_AG7648){
if(psu_id==1)
r_data=i2c_devname_read_word("PSU1_PMBUS", 0x90);
else
r_data=i2c_devname_read_word("PSU2_PMBUS", 0x90);
}
else{
if(psu_id==1)
r_data=i2c_devname_read_word("PSU1_PMBUS_POE", 0x90);
else
r_data=i2c_devname_read_word("PSU2_PMBUS_POE", 0x90);
}
if(r_data<0)
return ONLP_STATUS_E_INVALID;
fan_rpm=_onlp_psu_fan_val_to_rpm(r_data);
info->rpm = fan_rpm;
/* get speed percentage from rpm */
info->percentage = (info->rpm * 100.0) / MAX_PSU_FAN_SPEED;
if(info->percentage>100)
strcpy(info->model,"ONLP_FAN_MODE_LAST");
else if(info->percentage==100)
strcpy(info->model,"ONLP_FAN_MODE_MAX");
else if(info->percentage>=75&&info->percentage<100)
strcpy(info->model,"ONLP_FAN_MODE_FAST");
else if(info->percentage>=35&&info->percentage<75)
strcpy(info->model,"ONLP_FAN_MODE_NORMAL");
else if(info->percentage>0&&info->percentage<35)
strcpy(info->model,"ONLP_FAN_MODE_SLOW");
else if(info->percentage<=0)
strcpy(info->model,"ONLP_FAN_MODE_OFF");
else{}
#endif
return ONLP_STATUS_OK;
}
/*
* This function will be called prior to all of onlp_fani_* functions.
*/
int
onlp_fani_init(void)
{
int rc;
rc=_onlp_fan_board_init();
return rc;
}
int
onlp_fani_info_get(onlp_oid_t id, onlp_fan_info_t* info)
{
int rc = 0;
int local_id;
VALIDATE(id);
local_id = ONLP_OID_ID_GET(id);
if (chassis_fan_count() == 0) {
local_id += 1;
}
*info = linfo[local_id];
switch (local_id)
{
case FAN_1_ON_PSU1:
case FAN_1_ON_PSU2:
rc = _onlp_fani_info_get_fan_on_psu(local_id, info);
break;
case FAN_1_ON_MAIN_BOARD:
case FAN_2_ON_MAIN_BOARD:
case FAN_3_ON_MAIN_BOARD:
case FAN_4_ON_MAIN_BOARD:
case FAN_5_ON_MAIN_BOARD:
case FAN_6_ON_MAIN_BOARD:
rc =_onlp_fani_info_get_fan(local_id, info);
break;
default:
rc = ONLP_STATUS_E_INVALID;
break;
}
return rc;
}
/*
* This function sets the speed of the given fan in RPM.
*
* This function will only be called if the fan supprots the RPM_SET
* capability.
*
* It is optional if you have no fans at all with this feature.
*/
int
onlp_fani_rpm_set(onlp_oid_t id, int rpm)
{ /*
the rpm is the actual rpm/1000. so 16 represents the 16000(max spd)
*/
int rc1, rc2;
int local_id;
int d1, d2;
int fan_tray;
VALIDATE(id);
local_id = ONLP_OID_ID_GET(id);
DEBUG_PRINT("local id %d, rpm %d\n", local_id, rpm);
if((local_id==FAN_1_ON_PSU1)||(local_id==FAN_1_ON_PSU2))
return ONLP_STATUS_E_UNSUPPORTED;
if (chassis_fan_count() == 0) {
return ONLP_STATUS_E_INVALID;
}
/* init the fan on the board*/
if(fan_initd==0)
_onlp_fan_board_init();
/* reject rpm=0 (rpm=0, stop fan) */
if (rpm == 0)
return ONLP_STATUS_E_INVALID;
/*get ret value for the speed set*/
FAN_TO_REG(rpm);
DEBUG_PRINT("local id %d, rpm %d(d1: %d, d2: %d)\n", local_id, rpm, d1, d2);
//return ONLP_STATUS_OK;
/*set the rpm speed */
fan_tray = _onlp_get_fan_tray(local_id);
if (fan_tray < 0 || fan_tray > 2)
return ONLP_STATUS_E_INVALID;
if (fan_tray == 0)
{
rc1 = i2c_devname_write_byte("FANCTRL1", 0x20 + 2 * (local_id - FAN_5_ON_MAIN_BOARD), d1);
rc2 = i2c_devname_write_byte("FANCTRL1", 0x21 + 2 * (local_id - FAN_5_ON_MAIN_BOARD), d2);
}else
{
rc1 = i2c_devname_write_byte("FANCTRL2", 0x20 + 2 * (local_id - FAN_1_ON_MAIN_BOARD), d1);
rc2 = i2c_devname_write_byte("FANCTRL2", 0x21 + 2 * (local_id - FAN_1_ON_MAIN_BOARD), d2);
}
if (rc1 < 0 || rc2 < 0)
{
return ONLP_STATUS_E_INVALID;
}
return ONLP_STATUS_OK;
}
/*set the percentage for the psu fan*/
/*
* This function sets the fan speed of the given OID as a percentage.
*
* This will only be called if the OID has the PERCENTAGE_SET
* capability.
*
* It is optional if you have no fans at all with this feature.
*/
int
onlp_fani_percentage_set(onlp_oid_t id, int p)
{
/*
p is between 0 and 100 ,p=100 represents 16000(max spd)
*/
int rpm_val;
int local_id;
int d1, d2;
int rc1, rc2;
int fan_tray;
VALIDATE(id);
local_id = ONLP_OID_ID_GET(id);
DEBUG_PRINT("local_id %d, percentage %d", local_id, p);
if((local_id==FAN_1_ON_PSU1)||(local_id==FAN_1_ON_PSU2))
return ONLP_STATUS_E_UNSUPPORTED;
if (chassis_fan_count() == 0) {
return ONLP_STATUS_E_INVALID;
}
/* init the fan on the board*/
if(fan_initd==0)
_onlp_fan_board_init();
/* reject p=0 (p=0, stop fan) */
if (p == 0){
return ONLP_STATUS_E_INVALID;
}
rpm_val=p* MAX_FAN_SPEED/100;
/*get ret value for the speed set*/
FAN_TO_REG(rpm_val);
DEBUG_PRINT("local_id %d, p %d, rpm_val %d(d1:%d, d2:%d)", local_id, p, rpm_val, d1, d2);
//return ONLP_STATUS_OK;
/*set the rpm speed */
fan_tray = _onlp_get_fan_tray(local_id);
if (fan_tray < 0 || fan_tray > 2)
return ONLP_STATUS_E_INVALID;
if (fan_tray == 0)
{
rc1 = i2c_devname_write_byte("FANCTRL1", 0x20 + 2 * (local_id - FAN_5_ON_MAIN_BOARD), d1);
rc2 = i2c_devname_write_byte("FANCTRL1", 0x21 + 2 * (local_id - FAN_5_ON_MAIN_BOARD), d2);
}else
{
rc1 = i2c_devname_write_byte("FANCTRL2", 0x20 + 2 * (local_id - FAN_1_ON_MAIN_BOARD) , d1);
rc2 = i2c_devname_write_byte("FANCTRL2", 0x21 + 2 * (local_id - FAN_1_ON_MAIN_BOARD) , d2);
}
if (rc1 < 0 || rc2 < 0)
{
return ONLP_STATUS_E_INVALID;
}
return ONLP_STATUS_OK;
}
/*
* This function sets the fan speed of the given OID as per
* the predefined ONLP fan speed modes: off, slow, normal, fast, max.
*
* Interpretation of these modes is up to the platform.
*
*/
int
onlp_fani_mode_set(onlp_oid_t id, onlp_fan_mode_t mode)
{
return ONLP_STATUS_E_UNSUPPORTED;
}
/*
* This function sets the fan direction of the given OID.
*
* This function is only relevant if the fan OID supports both direction
* capabilities.
*
* This function is optional unless the functionality is available.
*/
int
onlp_fani_dir_set(onlp_oid_t id, onlp_fan_dir_t dir)
{
return ONLP_STATUS_E_UNSUPPORTED;
}
/*
* Generic fan ioctl. Optional.
*/
int
onlp_fani_ioctl(onlp_oid_t id, va_list vargs)
{
return ONLP_STATUS_E_UNSUPPORTED;
}

View File

@@ -0,0 +1,443 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014, 2015 Big Switch Networks, Inc.
* Copyright 2016 Accton Technology Corporation.
* Copyright 2017 Delta Networks, Inc
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <onlp/platformi/ledi.h>
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <onlplib/mmap.h>
#include "platform_lib.h"
#include "x86_64_delta_ag7648_int.h"
#include "x86_64_delta_i2c.h"
#define VALIDATE(_id) \
do { \
if(!ONLP_OID_IS_LED(_id)) { \
return ONLP_STATUS_E_INVALID; \
} \
} while(0)
#define CPLD_NAME1 "SYSCPLD"
#define CPLD_NAME2 "MASTERCPLD"
#define CPLD_NAME3 "SLAVECPLD"
#define CPLD_LED_REG_BITS (0X3) //the reg bits
#define CPLD_LED_FAN_TRAY_REG (0X8)
#define CPLD_LED_FAN_TRAY0_REG_OFFSET (0X0)
#define CPLD_LED_FAN_TRAY1_REG_OFFSET (0X2)
#define CPLD_LED_FAN_TRAY2_REG_OFFSET (0X4)
#define CPLD_LED_POWER_REG (0X6)
#define CPLD_LED_POWER_REG_OFFSET (0X6)
#define CPLD_LED_SYS_REG (0X7)
#define CPLD_LED_SYS_REG_OFFSET (0X5)
#define CPLD_LED_LOCATOR_REG_OFFSET (0X3)
#define CPLD_LED_FAN_REG (0X9)
#define CPLD_LED_FAN_REG_OFFSET (0X3)
/*
* Get the information for the given LED OID.
*/
static onlp_led_info_t linfo[] =
{
{ }, /* Not used */
{
{ ONLP_LED_ID_CREATE(LED_SYS), "sys", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_GREEN_BLINKING |ONLP_LED_CAPS_GREEN |
ONLP_LED_CAPS_YELLOW_BLINKING | ONLP_LED_CAPS_YELLOW ,
},
{
{ ONLP_LED_ID_CREATE(LED_FAN), "fan", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_YELLOW_BLINKING |
ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_YELLOW,
},
{
{ ONLP_LED_ID_CREATE(LED_LOCATOR), "locator", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN |
ONLP_LED_CAPS_GREEN_BLINKING ,
},
{
{ ONLP_LED_ID_CREATE(LED_POWER), "power", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN |
ONLP_LED_CAPS_YELLOW_BLINKING,
},
{
{ ONLP_LED_ID_CREATE(LED_FAN_TRAY0), "fan_tray0", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN |
ONLP_LED_CAPS_YELLOW,
},
{
{ ONLP_LED_ID_CREATE(LED_FAN_TRAY1), "fan_tray1", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN |
ONLP_LED_CAPS_YELLOW,
},
{
{ ONLP_LED_ID_CREATE(LED_FAN_TRAY2), "fan_tray2", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN |
ONLP_LED_CAPS_YELLOW,
},
};
static int conver_led_light_mode_to_onl(uint32_t id, int led_ligth_mode)
{
switch (id) {
case LED_SYS:
switch (led_ligth_mode) {
case SYS_LED_MODE_GREEN_BLINKING: return ONLP_LED_MODE_GREEN_BLINKING;
case SYS_LED_MODE_GREEN: return ONLP_LED_MODE_GREEN;
case SYS_LED_MODE_YELLOW: return ONLP_LED_MODE_YELLOW;
case SYS_LED_MODE_YELLOW_BLINKING: return ONLP_LED_MODE_YELLOW_BLINKING;
default: return ONLP_LED_MODE_GREEN_BLINKING;
}
case LED_FAN:
switch (led_ligth_mode) {
case FAN_LED_MODE_OFF: return ONLP_LED_MODE_OFF;
case FAN_LED_MODE_GREEN: return ONLP_LED_MODE_GREEN;
case FAN_LED_MODE_YELLOW: return ONLP_LED_MODE_YELLOW;
case FAN_LED_MODE_YELLOW_BLINKING: return ONLP_LED_MODE_YELLOW_BLINKING;
default: return ONLP_LED_MODE_OFF;
}
case LED_LOCATOR:
switch (led_ligth_mode) {
case LOCATOR_LED_MODE_OFF: return ONLP_LED_MODE_OFF;
case LOCATOR_LED_MODE_GREEN: return ONLP_LED_MODE_GREEN;
case LOCATOR_LED_MODE_GREEN_BLINKING: return ONLP_LED_MODE_GREEN_BLINKING;
default: return ONLP_LED_MODE_OFF;
}
case LED_POWER:
switch (led_ligth_mode) {
case POWER_LED_MODE_OFF: return ONLP_LED_MODE_OFF;
case POWER_LED_MODE_GREEN: return ONLP_LED_MODE_GREEN;
case POWER_LED_MODE_YELLOW_BLINKING: return ONLP_LED_MODE_YELLOW_BLINKING;
default: return ONLP_LED_MODE_OFF;
}
case LED_FAN_TRAY0:
case LED_FAN_TRAY1:
case LED_FAN_TRAY2:
switch (led_ligth_mode) {
case FAN_TRAY_LED_MODE_OFF: return ONLP_LED_MODE_OFF;
case FAN_TRAY_LED_MODE_GREEN: return ONLP_LED_MODE_GREEN;
case FAN_TRAY_LED_MODE_YELLOW: return ONLP_LED_MODE_YELLOW_BLINKING;
default: return ONLP_LED_MODE_OFF;
}
}
return ONLP_LED_MODE_OFF;
}
static int conver_onlp_led_light_mode_to_driver(uint32_t id, int led_ligth_mode)
{
switch (id) {
case LED_SYS:
switch (led_ligth_mode) {
case ONLP_LED_MODE_GREEN_BLINKING: return SYS_LED_MODE_GREEN_BLINKING;
case ONLP_LED_MODE_GREEN: return SYS_LED_MODE_GREEN;
case ONLP_LED_MODE_YELLOW: return SYS_LED_MODE_YELLOW ;
case ONLP_LED_MODE_YELLOW_BLINKING: return SYS_LED_MODE_YELLOW_BLINKING;
default: return SYS_LED_MODE_UNKNOWN;
}
case LED_FAN:
switch (led_ligth_mode) {
case ONLP_LED_MODE_OFF: return FAN_LED_MODE_OFF;
case ONLP_LED_MODE_GREEN: return FAN_LED_MODE_GREEN ;
case ONLP_LED_MODE_YELLOW: return FAN_LED_MODE_YELLOW;
case ONLP_LED_MODE_YELLOW_BLINKING: return FAN_LED_MODE_YELLOW_BLINKING;
default: return FAN_LED_MODE_UNKNOWN;
}
case LED_LOCATOR:
switch (led_ligth_mode) {
case ONLP_LED_MODE_OFF: return LOCATOR_LED_MODE_OFF;
case ONLP_LED_MODE_GREEN: return LOCATOR_LED_MODE_GREEN;
case ONLP_LED_MODE_GREEN_BLINKING: return LOCATOR_LED_MODE_GREEN_BLINKING;
default: return LOCATOR_LED_MODE_UNKNOWN;
}
case LED_POWER:
switch (led_ligth_mode) {
case ONLP_LED_MODE_OFF: return POWER_LED_MODE_OFF;
case ONLP_LED_MODE_GREEN: return POWER_LED_MODE_GREEN;
case ONLP_LED_MODE_YELLOW_BLINKING: return POWER_LED_MODE_YELLOW_BLINKING;
default: return POWER_LED_MODE_UNKNOWN;
}
case LED_FAN_TRAY0:
case LED_FAN_TRAY1:
case LED_FAN_TRAY2:
switch (led_ligth_mode) {
case ONLP_LED_MODE_OFF: return FAN_TRAY_LED_MODE_OFF;
case ONLP_LED_MODE_GREEN: return FAN_TRAY_LED_MODE_GREEN;
case ONLP_LED_MODE_YELLOW_BLINKING: return FAN_TRAY_LED_MODE_YELLOW;
default: return FAN_TRAY_LED_MODE_UNKNOWN;
}
}
return ONLP_LED_MODE_OFF;
}
/*
* This function will be called prior to any other onlp_ledi_* functions.
*/
int
onlp_ledi_init(void)
{
return ONLP_STATUS_OK;
}
static int
onlp_ledi_oid_to_internal_id(onlp_oid_t id)
{
enum ag7648_product_id pid = get_product_id();
int lid = ONLP_OID_ID_GET(id);
if (pid != PID_AG7648) {
return lid;
}
switch (lid) {
case 1: return LED_SYS;
case 2: return LED_FAN;
case 3: return LED_LOCATOR;
case 4: return LED_POWER;
case 5: return LED_FAN_TRAY0;
case 6: return LED_FAN_TRAY1;
case 7: return LED_FAN_TRAY2;
}
return lid;
}
int
onlp_ledi_info_get(onlp_oid_t id, onlp_led_info_t* info)
{
int r_data,m_data;
int lid = onlp_ledi_oid_to_internal_id(id);
VALIDATE(id);
/* Set the onlp_oid_hdr_t and capabilities */
*info = linfo[lid];
DEBUG_PRINT("id %u lid %d\n", id, lid);
switch (lid)
{
case LED_POWER:
r_data = i2c_devname_read_byte(CPLD_NAME2, CPLD_LED_POWER_REG);
if (r_data < 0)
return ONLP_STATUS_E_INTERNAL;
m_data = (r_data >> CPLD_LED_POWER_REG_OFFSET) & CPLD_LED_REG_BITS;
break;
case LED_SYS:
r_data = i2c_devname_read_byte(CPLD_NAME2, CPLD_LED_SYS_REG);
if (r_data < 0)
return ONLP_STATUS_E_INTERNAL;
m_data = (r_data >> CPLD_LED_SYS_REG_OFFSET) & CPLD_LED_REG_BITS;
break;
case LED_LOCATOR:
r_data = i2c_devname_read_byte(CPLD_NAME2, CPLD_LED_SYS_REG);
if (r_data < 0)
return ONLP_STATUS_E_INTERNAL;
m_data = (r_data >> CPLD_LED_LOCATOR_REG_OFFSET) & CPLD_LED_REG_BITS;
break;
case LED_FAN:
r_data = i2c_devname_read_byte(CPLD_NAME2, CPLD_LED_FAN_REG);
if (r_data < 0)
return ONLP_STATUS_E_INTERNAL;
m_data = (r_data >> CPLD_LED_FAN_REG_OFFSET) & CPLD_LED_REG_BITS;
break;
case LED_FAN_TRAY0:
r_data = i2c_devname_read_byte(CPLD_NAME2, CPLD_LED_FAN_TRAY_REG);
if (r_data < 0)
return ONLP_STATUS_E_INTERNAL;
m_data = (r_data >> CPLD_LED_FAN_TRAY0_REG_OFFSET) & CPLD_LED_REG_BITS;
break;
case LED_FAN_TRAY1:
r_data = i2c_devname_read_byte(CPLD_NAME2, CPLD_LED_FAN_TRAY_REG);
if (r_data < 0)
return ONLP_STATUS_E_INTERNAL;
m_data = (r_data >> CPLD_LED_FAN_TRAY1_REG_OFFSET) & CPLD_LED_REG_BITS;
break;
case LED_FAN_TRAY2:
r_data = i2c_devname_read_byte(CPLD_NAME2, CPLD_LED_FAN_TRAY_REG);
if (r_data < 0)
return ONLP_STATUS_E_INTERNAL;
m_data = (r_data >> CPLD_LED_FAN_TRAY2_REG_OFFSET) & CPLD_LED_REG_BITS;
break;
default:
return ONLP_STATUS_E_INTERNAL;
}
info->mode = conver_led_light_mode_to_onl(lid, m_data);
/* Set the on/off status */
if (info->mode != ONLP_LED_MODE_OFF) {
info->status |= ONLP_LED_STATUS_ON;
}
return ONLP_STATUS_OK;
}
/*
* This function puts the LED into the given mode. It is a more functional
* interface for multimode LEDs.
*
* Only modes reported in the LED's capabilities will be attempted.
*/
int
onlp_ledi_mode_set(onlp_oid_t id, onlp_led_mode_t mode)
{
int r_data,driver_mode, rc;
int reg;
int lid = onlp_ledi_oid_to_internal_id(id);
VALIDATE(id);
driver_mode = conver_onlp_led_light_mode_to_driver(lid, mode);
if((driver_mode==SYS_LED_MODE_UNKNOWN)||(driver_mode==FAN_LED_MODE_UNKNOWN)||\
(driver_mode==POWER_LED_MODE_UNKNOWN)||(driver_mode==LOCATOR_LED_MODE_UNKNOWN))
return ONLP_STATUS_E_UNSUPPORTED;
switch (lid)
{
case LED_POWER:
reg = CPLD_LED_POWER_REG;
r_data = i2c_devname_read_byte(CPLD_NAME2, CPLD_LED_POWER_REG);
if (r_data < 0)
return ONLP_STATUS_E_INTERNAL;
r_data &= ~(CPLD_LED_REG_BITS << CPLD_LED_POWER_REG_OFFSET);
r_data |= (driver_mode & CPLD_LED_REG_BITS ) << CPLD_LED_POWER_REG_OFFSET;
break;
case LED_SYS:
reg = CPLD_LED_SYS_REG;
r_data = i2c_devname_read_byte(CPLD_NAME2, CPLD_LED_SYS_REG);
if (r_data < 0)
return ONLP_STATUS_E_INTERNAL;
r_data &= ~(CPLD_LED_REG_BITS << CPLD_LED_SYS_REG_OFFSET);
r_data |= (driver_mode & CPLD_LED_REG_BITS ) << CPLD_LED_SYS_REG_OFFSET;
break;
case LED_LOCATOR:
reg = CPLD_LED_SYS_REG;
r_data = i2c_devname_read_byte(CPLD_NAME2, CPLD_LED_SYS_REG);
if (r_data < 0)
return ONLP_STATUS_E_INTERNAL;
r_data &= ~(CPLD_LED_REG_BITS << CPLD_LED_LOCATOR_REG_OFFSET);
r_data |= (driver_mode & CPLD_LED_REG_BITS ) << CPLD_LED_LOCATOR_REG_OFFSET;
break;
case LED_FAN:
reg = CPLD_LED_FAN_REG;
r_data = i2c_devname_read_byte(CPLD_NAME2, CPLD_LED_FAN_REG);
if (r_data < 0)
return ONLP_STATUS_E_INTERNAL;
r_data &= ~(CPLD_LED_REG_BITS << CPLD_LED_FAN_REG_OFFSET);
r_data |= (driver_mode & CPLD_LED_REG_BITS ) << CPLD_LED_FAN_REG_OFFSET;
break;
case LED_FAN_TRAY0:
reg = CPLD_LED_FAN_TRAY_REG;
r_data = i2c_devname_read_byte(CPLD_NAME2, CPLD_LED_FAN_TRAY_REG);
if (r_data < 0)
return ONLP_STATUS_E_INTERNAL;
r_data &= ~(CPLD_LED_REG_BITS << CPLD_LED_FAN_TRAY0_REG_OFFSET);
r_data |= (driver_mode & CPLD_LED_REG_BITS ) << CPLD_LED_FAN_TRAY0_REG_OFFSET;
break;
case LED_FAN_TRAY1:
reg = CPLD_LED_FAN_TRAY_REG;
r_data = i2c_devname_read_byte(CPLD_NAME2, CPLD_LED_FAN_TRAY_REG);
if (r_data < 0)
return ONLP_STATUS_E_INTERNAL;
r_data &= ~(CPLD_LED_REG_BITS << CPLD_LED_FAN_TRAY1_REG_OFFSET);
r_data |= (driver_mode & CPLD_LED_REG_BITS ) << CPLD_LED_FAN_TRAY1_REG_OFFSET;
break;
case LED_FAN_TRAY2:
reg = CPLD_LED_FAN_TRAY_REG;
r_data = i2c_devname_read_byte(CPLD_NAME2, CPLD_LED_FAN_TRAY_REG);
if (r_data < 0)
return ONLP_STATUS_E_INTERNAL;
r_data &= ~(CPLD_LED_REG_BITS << CPLD_LED_FAN_TRAY2_REG_OFFSET);
r_data |= (driver_mode & CPLD_LED_REG_BITS ) << CPLD_LED_FAN_TRAY2_REG_OFFSET;
break;
default:
return ONLP_STATUS_E_INTERNAL;
}
rc=i2c_devname_write_byte(CPLD_NAME2, reg, r_data);
if(rc<0){
return ONLP_STATUS_E_INTERNAL;
}
return ONLP_STATUS_OK;
}
/*
* Turn an LED on or off.
*
* This function will only be called if the LED OID supports the ONOFF
* capability.
*
* What 'on' means in terms of colors or modes for multimode LEDs is
* up to the platform to decide. This is intended as baseline toggle mechanism.
*/
int
onlp_ledi_set(onlp_oid_t id, int on_or_off)
{
if (!on_or_off) {
return onlp_ledi_mode_set(id, ONLP_LED_MODE_OFF);
}
return ONLP_STATUS_E_UNSUPPORTED;
}
/*
* Generic LED ioctl interface.
*/
int
onlp_ledi_ioctl(onlp_oid_t id, va_list vargs)
{
return ONLP_STATUS_E_UNSUPPORTED;
}

View File

@@ -0,0 +1,9 @@
###############################################################################
#
#
#
###############################################################################
LIBRARY := x86_64_delta_ag7648
$(LIBRARY)_SUBDIR := $(dir $(lastword $(MAKEFILE_LIST)))
include $(BUILDER)/lib.mk

View File

@@ -0,0 +1,186 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2015 Accton Technology Corporation.
* Copyright 2017 Delta Networks, Inc.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <AIM/aim.h>
#include "platform_lib.h"
int deviceNodeWrite(char *filename, char *buffer, int buf_size, int data_len)
{
int fd;
int len;
if ((buffer == NULL) || (buf_size < 0)) {
return -1;
}
if ((fd = open(filename, O_WRONLY, S_IWUSR)) == -1) {
return -1;
}
if ((len = write(fd, buffer, buf_size)) < 0) {
close(fd);
return -1;
}
if ((close(fd) == -1)) {
return -1;
}
if ((len > buf_size) || (data_len != 0 && len != data_len)) {
return -1;
}
return 0;
}
int deviceNodeWriteInt(char *filename, int value, int data_len)
{
char buf[8] = {0};
sprintf(buf, "%d", value);
return deviceNodeWrite(filename, buf, sizeof(buf)-1, data_len);
}
int deviceNodeReadBinary(char *filename, char *buffer, int buf_size, int data_len)
{
int fd;
int len;
if ((buffer == NULL) || (buf_size < 0)) {
return -1;
}
if ((fd = open(filename, O_RDONLY)) == -1) {
return -1;
}
if ((len = read(fd, buffer, buf_size)) < 0) {
close(fd);
return -1;
}
if ((close(fd) == -1)) {
return -1;
}
if ((len > buf_size) || (data_len != 0 && len != data_len)) {
return -1;
}
return 0;
}
int deviceNodeReadString(char *filename, char *buffer, int buf_size, int data_len)
{
int ret;
if (data_len >= buf_size || data_len < 0) {
return -1;
}
ret = deviceNodeReadBinary(filename, buffer, buf_size-1, data_len);
if (ret == 0) {
if (data_len) {
buffer[data_len] = '\0';
}
else {
buffer[buf_size-1] = '\0';
}
}
return ret;
}
#define I2C_PSU_MODEL_NAME_LEN 13
psu_type_t get_psu_type(int id, char* modelname, int modelname_len)
{
DEBUG_PRINT("id %d, modelname %s, length %d\r\n", id, modelname, modelname_len);
#if 0
char *node = NULL;
char model_name[I2C_PSU_MODEL_NAME_LEN + 1] = {0};
/* Check AC model name */
node = (id == PSU1_ID) ? PSU1_AC_HWMON_NODE(psu_model_name) : PSU2_AC_HWMON_NODE(psu_model_name);
if (deviceNodeReadString(node, model_name, sizeof(model_name), 0) == 0) {
if (strncmp(model_name, "CPR-4011-4M11", strlen("CPR-4011-4M11")) == 0) {
if (modelname) {
strncpy(modelname, model_name, modelname_len-1);
}
return PSU_TYPE_AC_F2B;
}
else if (strncmp(model_name, "CPR-4011-4M21", strlen("CPR-4011-4M21")) == 0) {
if (modelname) {
strncpy(modelname, model_name, modelname_len-1);
}
return PSU_TYPE_AC_B2F;
}
}
/* Check DC model name */
memset(model_name, 0, sizeof(model_name));
node = (id == PSU1_ID) ? PSU1_DC_HWMON_NODE(psu_model_name) : PSU2_DC_HWMON_NODE(psu_model_name);
if (deviceNodeReadString(node, model_name, sizeof(model_name), 0) == 0) {
if (strncmp(model_name, "um400d01G", strlen("um400d01G")) == 0) {
if (modelname) {
strncpy(modelname, model_name, modelname_len-1);
}
return PSU_TYPE_DC_48V_B2F;
}
else if (strncmp(model_name, "um400d01-01G", strlen("um400d01-01G")) == 0) {
if (modelname) {
strncpy(modelname, model_name, modelname_len-1);
}
return PSU_TYPE_DC_48V_F2B;
}
}
#endif
return PSU_TYPE_UNKNOWN;
}
enum ag7648_product_id get_product_id(void)
{
return PID_AG7648;
}
int chassis_fan_count(void)
{
return 6 ;
}
int chassis_led_count(void)
{
return 7;
}

View File

@@ -0,0 +1,148 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2015 Accton Technology Corporation.
* Copyright 2017 Delta Networks, Inc.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#ifndef __PLATFORM_LIB_H__
#define __PLATFORM_LIB_H__
#include "x86_64_delta_ag7648_log.h"
#define PSU1_ID 1
#define PSU2_ID 2
#define CHASSIS_FAN_COUNT 6
#define CHASSIS_THERMAL_COUNT 4
#define CHASSIS_PSU_COUNT 2
typedef enum psu_type {
PSU_TYPE_UNKNOWN,
PSU_TYPE_AC_F2B,
PSU_TYPE_AC_B2F,
PSU_TYPE_DC_48V_F2B,
PSU_TYPE_DC_48V_B2F
} psu_type_t;
psu_type_t get_psu_type(int id, char* modelname, int modelname_len);
#define DEBUG_MODE 0
#if (DEBUG_MODE == 1)
#define DEBUG_PRINT(format, ...) \
{\
printf("[%s:%d] ", __FUNCTION__, __LINE__);\
printf(format, __VA_ARGS__); \
}
#else
#define DEBUG_PRINT(format, ...)
#endif
enum onlp_fan_duty_cycle_percentage
{
FAN_IDLE_RPM = 7500,
FAN_LEVEL1_RPM = 10000,
FAN_LEVEL2_RPM = 13000,
FAN_LEVEL3_RPM = 16000,
FAN_LEVEL4_RPM = 19000,
};
enum ag7648_product_id {
PID_AG7648= 2,
PID_UNKNOWN
};
/* LED related data */
enum sys_led_light_mode {
SYS_LED_MODE_GREEN_BLINKING = 0,
SYS_LED_MODE_GREEN,
SYS_LED_MODE_YELLOW,
SYS_LED_MODE_YELLOW_BLINKING,
SYS_LED_MODE_UNKNOWN
};
enum fan_led_light_mode {
FAN_LED_MODE_OFF = 0,
FAN_LED_MODE_YELLOW,
FAN_LED_MODE_GREEN,
FAN_LED_MODE_YELLOW_BLINKING,
FAN_LED_MODE_UNKNOWN
};
enum psu_led_light_mode {
PSU_LED_MODE_OFF = 0,
PSU_LED_MODE_GREEN,
PSU_LED_MODE_YELLOW,
PSU_LED_MODE_YELLOW_BLINKING,
PSU_LED_MODE_RESERVERD,
PSU_LED_MODE_UNKNOWN
};
enum locator_led_light_mode {
LOCATOR_LED_MODE_OFF = 0,
LOCATOR_LED_MODE_GREEN_BLINKING,
LOCATOR_LED_MODE_GREEN,
LOCATOR_LED_MODE_RESERVERD,
LOCATOR_LED_MODE_UNKNOWN
};
enum power_led_light_mode {
POWER_LED_MODE_OFF = 0,
POWER_LED_MODE_YELLOW,
POWER_LED_MODE_GREEN,
POWER_LED_MODE_YELLOW_BLINKING,
POWER_LED_MODE_UNKNOWN
};
enum fan_tray_led_light_mode {
FAN_TRAY_LED_MODE_OFF = 0,
FAN_TRAY_LED_MODE_GREEN,
FAN_TRAY_LED_MODE_YELLOW,
FAN_TRAY_LED_MODE_RESERVERD,
FAN_TRAY_LED_MODE_UNKNOWN
};
typedef enum onlp_led_id
{
LED_RESERVED = 0,
LED_SYS,
LED_FAN,
LED_LOCATOR,
LED_POWER,
LED_FAN_TRAY0,
LED_FAN_TRAY1,
LED_FAN_TRAY2,
} onlp_led_id_t;
enum ag7648_product_id get_product_id(void);
int chassis_fan_count(void);
int chassis_led_count(void);
typedef enum platform_id_e {
PLATFORM_ID_UNKNOWN,
PLATFORM_ID_DELTA_AG7648_R0,
} platform_id_t;
extern platform_id_t platform_id;
#endif /* __PLATFORM_LIB_H__ */

View File

@@ -0,0 +1,357 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014, 2015 Big Switch Networks, Inc.
* Copyright 2016 Accton Technology Corporation.
* Copyright 2017 Delta Networks, Inc
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <onlp/platformi/psui.h>
#include <onlplib/mmap.h>
#include <stdio.h>
#include <string.h>
#include "platform_lib.h"
#include "x86_64_delta_ag7648_int.h"
#include "x86_64_delta_i2c.h"
#define CPLD_PSU_NAME "MASTERCPLD"
#define PSU_STATUS_PRESENT 1
#define PSU_STATUS_POWER_GOOD 1
#define PSU_STATUS_REG (0X03)
#define PSU_STATUS_PRESENT_BIT(ch) (0x8<<4*(ch-1))
#define PSU_STATUS_GOOD_BIT(ch) (0x4<<4*(ch-1))
#define PSU_STATUS_PRESENT_OFFSET(ch) (4*ch-1)
#define PSU_STATUS_GOOD_OFFSET(ch) (0x2+4*(ch-1))
#define PSU_PNBUS_VIN_REG (0x88)
#define PSU_PNBUS_IIN_REG (0x89)
#define PSU_PNBUS_PIN_REG (0x97)
#define PSU_PNBUS_VOUT_REG (0x8b)
#define PSU_PNBUS_IOUT_REG (0x8c)
#define PSU_PNBUS_POUT_REG (0x96)
#define PSU_PNBUS_SERIAL_REG (0x39)
#define PSU_PNBUS_MODEL_REG (0xc)
#define VALIDATE(_id) \
do { \
if(!ONLP_OID_IS_PSU(_id)) { \
return ONLP_STATUS_E_INVALID; \
} \
} while(0)
static long psu_data_convert(unsigned int d, int mult)
{
long X, Y, N, n;
Y = d & 0x07FF;
N = (d >> 11) & 0x0f;
n = d & 0x8000 ? 1 : 0;
if (n)
X = (Y * mult) / ((1<<(((~N)&0xf)+1))) ;
else
X = (Y * mult) * (N=(1<<(N&0xf)));
return X;
}
static long psu_data_convert_16(unsigned int d, int mult)
{
long X;
X = (d * mult) / (1 << 9);
return X;
}
static int
psu_status_info_get(int id, char *node)
{
int ret;
char r_data;
ret=i2c_devname_read_byte(CPLD_PSU_NAME,PSU_STATUS_REG);
if(ret<0)
return -1;
if (PSU1_ID == id) {
if(!strcmp("present",node))
r_data=!((ret& PSU_STATUS_PRESENT_BIT(id))>> PSU_STATUS_PRESENT_OFFSET(id));
else if(!strcmp("good",node))
r_data=((ret& PSU_STATUS_GOOD_BIT(id))>> PSU_STATUS_GOOD_OFFSET(id));
else
r_data=-1;
}
else if (PSU2_ID == id) {
if(!strcmp("present",node))
r_data=!((ret& PSU_STATUS_PRESENT_BIT(id))>> PSU_STATUS_PRESENT_OFFSET(id));
else if(!strcmp("good",node))
r_data=((ret& PSU_STATUS_GOOD_BIT(id))>> PSU_STATUS_GOOD_OFFSET(id));
else
r_data=-1;
}
else{
r_data=-1;
}
return r_data;
}
static int
psu_value_info_get(int id, char *type)
{
int ret;
char *dev_name;
int reg_offset;
if(PSU1_ID == id)
dev_name="PSU1_PMBUS";
else
dev_name="PSU2_PMBUS";
if(!strcmp(type,"vin"))
reg_offset=PSU_PNBUS_VIN_REG;
else if(!strcmp(type,"iin"))
reg_offset=PSU_PNBUS_IIN_REG;
else if(!strcmp(type,"pin"))
reg_offset=PSU_PNBUS_PIN_REG;
else if(!strcmp(type,"vout"))
reg_offset=PSU_PNBUS_VOUT_REG;
else if(!strcmp(type,"iout"))
reg_offset=PSU_PNBUS_IOUT_REG;
else
reg_offset=PSU_PNBUS_POUT_REG;
ret=i2c_devname_read_word(dev_name,reg_offset);
if(ret<0)
return -1;
return ret;
}
static int
psu_serial_model_info_get(int id,char *type,char*data,int data_len)
{
int i,r_data,re_cnt;
char *dev_name;
int reg_offset;
if(PSU1_ID == id)
dev_name="PSU1_EEPROM";
else
dev_name="PSU2_EEPROM";
if(!strcmp(type,"serial"))
reg_offset=PSU_PNBUS_SERIAL_REG;
else
reg_offset=PSU_PNBUS_MODEL_REG;
for(i=0;i<data_len;i++){
re_cnt=3;
while(re_cnt){
r_data=i2c_devname_read_byte(dev_name,reg_offset+i);
if(r_data<0){
re_cnt--;
continue;
}
data[i]=r_data;
break;
}
if(re_cnt==0){
AIM_LOG_ERROR("Unable to read the %d reg \r\n",i);
return ONLP_STATUS_E_INTERNAL;
}
}
return ONLP_STATUS_OK;
}
int
onlp_psui_init(void)
{
return ONLP_STATUS_OK;
}
/*
* Get all information about the given PSU oid.
*/
static onlp_psu_info_t pinfo[] =
{
{ }, /* Not used */
{
{ ONLP_PSU_ID_CREATE(PSU1_ID), "PSU-1", 0 },
},
{
{ ONLP_PSU_ID_CREATE(PSU2_ID), "PSU-2", 0 },
}
};
int
onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info)
{
int val = 0;
int ret = ONLP_STATUS_OK;
int index = ONLP_OID_ID_GET(id);
psu_type_t psu_type;
int r_data;
char sn_data[15]={0};
char model_data[17]={0};
VALIDATE(id);
memset(info, 0, sizeof(onlp_psu_info_t));
*info = pinfo[index]; /* Set the onlp_oid_hdr_t */
/* Get the present state */
val=psu_status_info_get(index, "present");
if (val<0) {
AIM_LOG_INFO("Unable to read PSU %d present value)\r\n", index);
return ONLP_STATUS_E_INVALID;
}
if (val != PSU_STATUS_PRESENT) {
info->status &= ~ONLP_PSU_STATUS_PRESENT;
return ONLP_STATUS_OK;
}
info->status |= ONLP_PSU_STATUS_PRESENT;
/* Get power good status */
val=psu_status_info_get(index,"good");
if (val<0) {
AIM_LOG_INFO("Unable to read PSU %d good value)\r\n", index);
return ONLP_STATUS_E_INVALID;
}
if (val != PSU_STATUS_POWER_GOOD) {
info->status |= ONLP_PSU_STATUS_FAILED;
}
/* Get PSU type
*/
psu_type = get_psu_type(index, info->model, sizeof(info->model));
switch (psu_type) {
case PSU_TYPE_AC_F2B:
case PSU_TYPE_AC_B2F:
info->caps = ONLP_PSU_CAPS_AC;
ret = ONLP_STATUS_OK;
break;
case PSU_TYPE_UNKNOWN: /* User insert a unknown PSU or unplugged.*/
info->status |= ONLP_PSU_STATUS_UNPLUGGED;
info->status &= ~ONLP_PSU_STATUS_FAILED;
ret = ONLP_STATUS_OK;
break;
default:
ret = ONLP_STATUS_E_UNSUPPORTED;
break;
}
/* Get PSU vin,vout*/
r_data=psu_value_info_get(index,"vin");
if (r_data<0) {
AIM_LOG_INFO("Unable to read PSU %d Vin value)\r\n", index);
return ONLP_STATUS_E_INVALID;
}
info->mvin=psu_data_convert(r_data,1000);
r_data=psu_value_info_get(index,"vout");
if (r_data<0) {
AIM_LOG_INFO("Unable to read PSU %d Vout value)\r\n", index);
return ONLP_STATUS_E_INVALID;
}
info->mvout=psu_data_convert_16(r_data,1000);
/* Get PSU iin, iout
*/
r_data=psu_value_info_get(index,"iin");
if (r_data<0) {
AIM_LOG_INFO("Unable to read PSU %d Iin value)\r\n", index);
return ONLP_STATUS_E_INVALID;
}
info->miin=psu_data_convert(r_data,1000);
r_data=psu_value_info_get(index,"iout");
if (r_data<0) {
AIM_LOG_INFO("Unable to read PSU %d Iout value)\r\n", index);
return ONLP_STATUS_E_INVALID;
}
info->miout=psu_data_convert(r_data,1000);
/* Get PSU pin, pout
*/
r_data=psu_value_info_get(index,"pin");
if (r_data<0) {
AIM_LOG_INFO("Unable to read PSU %d Pin value)\r\n", index);
return ONLP_STATUS_E_INVALID;
}
info->mpin=psu_data_convert(r_data,1000);
r_data=psu_value_info_get(index,"pout");
if (r_data<0) {
AIM_LOG_INFO("Unable to read PSU %d Pout value)\r\n", index);
return ONLP_STATUS_E_INVALID;
}
info->mpout=psu_data_convert(r_data,1000);
/* Get PSU serial
*/
ret=psu_serial_model_info_get(index,"serial",sn_data,14);
if (ret!=ONLP_STATUS_OK) {
AIM_LOG_INFO("Unable to read PSU %d SN value)\r\n", index);
return ONLP_STATUS_E_INVALID;
}
strcpy(info->serial,sn_data);
/* Get PSU model
*/
ret=psu_serial_model_info_get(index,"model",model_data,16);
if (ret!=ONLP_STATUS_OK) {
AIM_LOG_INFO("Unable to read PSU %d model value)\r\n", index);
return ONLP_STATUS_E_INVALID;
}
strcpy(info->model,model_data);
return ONLP_STATUS_OK;
}
int
onlp_psui_ioctl(onlp_oid_t pid, va_list vargs)
{
return ONLP_STATUS_E_UNSUPPORTED;
}

View File

@@ -0,0 +1,464 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014, 2015 Big Switch Networks, Inc.
* Copyright 2016 Accton Technology Corporation.
* Copyright 2017 Delta Networks, Inc
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <onlp/platformi/sfpi.h>
#include "platform_lib.h"
#include <x86_64_delta_ag7648/x86_64_delta_ag7648_config.h>
#include "x86_64_delta_ag7648_log.h"
#include "x86_64_delta_i2c.h"
#define SFP_PLUS_MIN_PORT 1
#define SFP_PLUS_MAX_PORT 48
#define QSFP_MIN_PORT 49
#define QSFP_MAX_PORT 54
#define SFP_PLUS_1_8_PRESENT_REG (0X2)
#define SFP_PLUS_9_16_PRESENT_REG (0X3)
#define SFP_PLUS_17_24_PRESENT_REG (0X4)
#define SFP_PLUS_25_32_PRESENT_REG (0X5)
#define SFP_PLUS_33_40_PRESENT_REG (0X6)
#define SFP_PLUS_41_48_PRESENT_REG (0X7)
#define SFP_PLUS_1_8_RX_LOS_REG (0XE)
#define SFP_PLUS_9_16_RX_LOS_REG (0XF)
#define SFP_PLUS_17_24_RX_LOS_REG (0X10)
#define SFP_PLUS_25_32_RX_LOS_REG (0X11)
#define SFP_PLUS_33_40_RX_LOS_REG (0X12)
#define SFP_PLUS_41_48_RX_LOS_REG (0X13)
#define SFP_PLUS_1_8_TX_DISABLE_REG (0X8)
#define SFP_PLUS_9_16_TX_DISABLE_REG (0X9)
#define SFP_PLUS_17_24_TX_DISABLE_REG (0XA)
#define SFP_PLUS_25_32_TX_DISABLE_REG (0XB)
#define SFP_PLUS_33_40_TX_DISABLE_REG (0XC)
#define SFP_PLUS_41_48_TX_DISABLE_REG (0XD)
#define QSFP_49_54_PRESENT_REG (0xC)
#define INVALID_REG (0xFF)
#define INVALID_REG_BIT (0xFF)
struct portCtrl{
int portId;
char cpldName[32];
int presentReg;
int presentRegBit;
int rxLosReg;
int rxLosRegBit;
int txDisableReg;
int txDisableRegBit;
};
#define CPLD_NAME1 "SYSCPLD"
#define CPLD_NAME2 "MASTERCPLD"
#define CPLD_NAME3 "SLAVECPLD"
static struct portCtrl gPortCtrl[] =
{
{1, CPLD_NAME3, SFP_PLUS_1_8_PRESENT_REG, 0, SFP_PLUS_1_8_RX_LOS_REG, 0, SFP_PLUS_1_8_TX_DISABLE_REG, 0},
{2, CPLD_NAME3, SFP_PLUS_1_8_PRESENT_REG, 1, SFP_PLUS_1_8_RX_LOS_REG, 1, SFP_PLUS_1_8_TX_DISABLE_REG, 1},
{3, CPLD_NAME3, SFP_PLUS_1_8_PRESENT_REG, 2, SFP_PLUS_1_8_RX_LOS_REG, 1, SFP_PLUS_1_8_TX_DISABLE_REG, 2},
{4, CPLD_NAME3, SFP_PLUS_1_8_PRESENT_REG, 3, SFP_PLUS_1_8_RX_LOS_REG, 2, SFP_PLUS_1_8_TX_DISABLE_REG, 3},
{5, CPLD_NAME3, SFP_PLUS_1_8_PRESENT_REG, 4, SFP_PLUS_1_8_RX_LOS_REG, 3, SFP_PLUS_1_8_TX_DISABLE_REG, 4},
{6, CPLD_NAME3, SFP_PLUS_1_8_PRESENT_REG, 5, SFP_PLUS_1_8_RX_LOS_REG, 4, SFP_PLUS_1_8_TX_DISABLE_REG, 5},
{7, CPLD_NAME3, SFP_PLUS_1_8_PRESENT_REG, 6, SFP_PLUS_1_8_RX_LOS_REG, 5, SFP_PLUS_1_8_TX_DISABLE_REG, 6},
{8, CPLD_NAME3, SFP_PLUS_1_8_PRESENT_REG, 7, SFP_PLUS_1_8_RX_LOS_REG, 6, SFP_PLUS_1_8_TX_DISABLE_REG, 7},
{9, CPLD_NAME3, SFP_PLUS_9_16_PRESENT_REG, 0, SFP_PLUS_9_16_RX_LOS_REG, 0, SFP_PLUS_9_16_TX_DISABLE_REG, 0},
{10, CPLD_NAME3, SFP_PLUS_9_16_PRESENT_REG, 1, SFP_PLUS_9_16_RX_LOS_REG, 1, SFP_PLUS_9_16_TX_DISABLE_REG, 1},
{11, CPLD_NAME3, SFP_PLUS_9_16_PRESENT_REG, 2, SFP_PLUS_9_16_RX_LOS_REG, 1, SFP_PLUS_9_16_TX_DISABLE_REG, 2},
{12, CPLD_NAME3, SFP_PLUS_9_16_PRESENT_REG, 3, SFP_PLUS_9_16_RX_LOS_REG, 2, SFP_PLUS_9_16_TX_DISABLE_REG, 3},
{13, CPLD_NAME3, SFP_PLUS_9_16_PRESENT_REG, 4, SFP_PLUS_9_16_RX_LOS_REG, 3, SFP_PLUS_9_16_TX_DISABLE_REG, 4},
{14, CPLD_NAME3, SFP_PLUS_9_16_PRESENT_REG, 5, SFP_PLUS_9_16_RX_LOS_REG, 4, SFP_PLUS_9_16_TX_DISABLE_REG, 5},
{15, CPLD_NAME3, SFP_PLUS_9_16_PRESENT_REG, 6, SFP_PLUS_9_16_RX_LOS_REG, 5, SFP_PLUS_9_16_TX_DISABLE_REG, 6},
{16, CPLD_NAME3, SFP_PLUS_9_16_PRESENT_REG, 7, SFP_PLUS_9_16_RX_LOS_REG, 6, SFP_PLUS_9_16_TX_DISABLE_REG, 7},
{17, CPLD_NAME3, SFP_PLUS_17_24_PRESENT_REG, 0, SFP_PLUS_17_24_RX_LOS_REG, 0, SFP_PLUS_17_24_TX_DISABLE_REG, 0},
{18, CPLD_NAME3, SFP_PLUS_17_24_PRESENT_REG, 1, SFP_PLUS_17_24_RX_LOS_REG, 1, SFP_PLUS_17_24_TX_DISABLE_REG, 1},
{19, CPLD_NAME3, SFP_PLUS_17_24_PRESENT_REG, 2, SFP_PLUS_17_24_RX_LOS_REG, 1, SFP_PLUS_17_24_TX_DISABLE_REG, 2},
{20, CPLD_NAME3, SFP_PLUS_17_24_PRESENT_REG, 3, SFP_PLUS_17_24_RX_LOS_REG, 2, SFP_PLUS_17_24_TX_DISABLE_REG, 3},
{21, CPLD_NAME3, SFP_PLUS_17_24_PRESENT_REG, 4, SFP_PLUS_17_24_RX_LOS_REG, 3, SFP_PLUS_17_24_TX_DISABLE_REG, 4},
{22, CPLD_NAME3, SFP_PLUS_17_24_PRESENT_REG, 5, SFP_PLUS_17_24_RX_LOS_REG, 4, SFP_PLUS_17_24_TX_DISABLE_REG, 5},
{23, CPLD_NAME3, SFP_PLUS_17_24_PRESENT_REG, 6, SFP_PLUS_17_24_RX_LOS_REG, 5, SFP_PLUS_17_24_TX_DISABLE_REG, 6},
{24, CPLD_NAME3, SFP_PLUS_17_24_PRESENT_REG, 7, SFP_PLUS_17_24_RX_LOS_REG, 6, SFP_PLUS_17_24_TX_DISABLE_REG, 7},
{25, CPLD_NAME3, SFP_PLUS_25_32_PRESENT_REG, 0, SFP_PLUS_25_32_RX_LOS_REG, 0, SFP_PLUS_25_32_TX_DISABLE_REG, 0},
{26, CPLD_NAME3, SFP_PLUS_25_32_PRESENT_REG, 1, SFP_PLUS_25_32_RX_LOS_REG, 1, SFP_PLUS_25_32_TX_DISABLE_REG, 1},
{27, CPLD_NAME3, SFP_PLUS_25_32_PRESENT_REG, 2, SFP_PLUS_25_32_RX_LOS_REG, 1, SFP_PLUS_25_32_TX_DISABLE_REG, 2},
{28, CPLD_NAME3, SFP_PLUS_25_32_PRESENT_REG, 3, SFP_PLUS_25_32_RX_LOS_REG, 2, SFP_PLUS_25_32_TX_DISABLE_REG, 3},
{29, CPLD_NAME3, SFP_PLUS_25_32_PRESENT_REG, 4, SFP_PLUS_25_32_RX_LOS_REG, 3, SFP_PLUS_25_32_TX_DISABLE_REG, 4},
{30, CPLD_NAME3, SFP_PLUS_25_32_PRESENT_REG, 5, SFP_PLUS_25_32_RX_LOS_REG, 4, SFP_PLUS_25_32_TX_DISABLE_REG, 5},
{31, CPLD_NAME3, SFP_PLUS_25_32_PRESENT_REG, 6, SFP_PLUS_25_32_RX_LOS_REG, 5, SFP_PLUS_25_32_TX_DISABLE_REG, 6},
{32, CPLD_NAME3, SFP_PLUS_25_32_PRESENT_REG, 7, SFP_PLUS_25_32_RX_LOS_REG, 6, SFP_PLUS_25_32_TX_DISABLE_REG, 7},
{33, CPLD_NAME3, SFP_PLUS_33_40_PRESENT_REG, 0, SFP_PLUS_33_40_RX_LOS_REG, 0, SFP_PLUS_33_40_TX_DISABLE_REG, 0},
{34, CPLD_NAME3, SFP_PLUS_33_40_PRESENT_REG, 1, SFP_PLUS_33_40_RX_LOS_REG, 1, SFP_PLUS_33_40_TX_DISABLE_REG, 1},
{35, CPLD_NAME3, SFP_PLUS_33_40_PRESENT_REG, 2, SFP_PLUS_33_40_RX_LOS_REG, 1, SFP_PLUS_33_40_TX_DISABLE_REG, 2},
{36, CPLD_NAME3, SFP_PLUS_33_40_PRESENT_REG, 3, SFP_PLUS_33_40_RX_LOS_REG, 2, SFP_PLUS_33_40_TX_DISABLE_REG, 3},
{37, CPLD_NAME3, SFP_PLUS_33_40_PRESENT_REG, 4, SFP_PLUS_33_40_RX_LOS_REG, 3, SFP_PLUS_33_40_TX_DISABLE_REG, 4},
{38, CPLD_NAME3, SFP_PLUS_33_40_PRESENT_REG, 5, SFP_PLUS_33_40_RX_LOS_REG, 4, SFP_PLUS_33_40_TX_DISABLE_REG, 5},
{39, CPLD_NAME3, SFP_PLUS_33_40_PRESENT_REG, 6, SFP_PLUS_33_40_RX_LOS_REG, 5, SFP_PLUS_33_40_TX_DISABLE_REG, 6},
{40, CPLD_NAME3, SFP_PLUS_33_40_PRESENT_REG, 7, SFP_PLUS_33_40_RX_LOS_REG, 6, SFP_PLUS_33_40_TX_DISABLE_REG, 7},
{41, CPLD_NAME3, SFP_PLUS_41_48_PRESENT_REG, 0, SFP_PLUS_41_48_RX_LOS_REG, 0, SFP_PLUS_41_48_TX_DISABLE_REG, 0},
{42, CPLD_NAME3, SFP_PLUS_41_48_PRESENT_REG, 1, SFP_PLUS_41_48_RX_LOS_REG, 1, SFP_PLUS_41_48_TX_DISABLE_REG, 1},
{43, CPLD_NAME3, SFP_PLUS_41_48_PRESENT_REG, 2, SFP_PLUS_41_48_RX_LOS_REG, 1, SFP_PLUS_41_48_TX_DISABLE_REG, 2},
{44, CPLD_NAME3, SFP_PLUS_41_48_PRESENT_REG, 3, SFP_PLUS_41_48_RX_LOS_REG, 2, SFP_PLUS_41_48_TX_DISABLE_REG, 3},
{45, CPLD_NAME3, SFP_PLUS_41_48_PRESENT_REG, 4, SFP_PLUS_41_48_RX_LOS_REG, 3, SFP_PLUS_41_48_TX_DISABLE_REG, 4},
{46, CPLD_NAME3, SFP_PLUS_41_48_PRESENT_REG, 5, SFP_PLUS_41_48_RX_LOS_REG, 4, SFP_PLUS_41_48_TX_DISABLE_REG, 5},
{47, CPLD_NAME3, SFP_PLUS_41_48_PRESENT_REG, 6, SFP_PLUS_41_48_RX_LOS_REG, 5, SFP_PLUS_41_48_TX_DISABLE_REG, 6},
{48, CPLD_NAME3, SFP_PLUS_41_48_PRESENT_REG, 7, SFP_PLUS_41_48_RX_LOS_REG, 6, SFP_PLUS_41_48_TX_DISABLE_REG, 7},
{49, CPLD_NAME2, QSFP_49_54_PRESENT_REG, 0, INVALID_REG, 0, INVALID_REG_BIT, 0},
{50, CPLD_NAME2, QSFP_49_54_PRESENT_REG, 1, INVALID_REG, 1, INVALID_REG_BIT, 1},
{51, CPLD_NAME2, QSFP_49_54_PRESENT_REG, 2, INVALID_REG, 1, INVALID_REG_BIT, 2},
{52, CPLD_NAME2, QSFP_49_54_PRESENT_REG, 3, INVALID_REG, 2, INVALID_REG_BIT, 3},
{53, CPLD_NAME2, QSFP_49_54_PRESENT_REG, 4, INVALID_REG, 3, INVALID_REG_BIT, 4},
{54, CPLD_NAME2, QSFP_49_54_PRESENT_REG, 5, INVALID_REG, 4, INVALID_REG_BIT, 5},
{0xFFFF, "", INVALID_REG, 0, INVALID_REG, 0, INVALID_REG_BIT, 0},
};
/************************************************************
*
* SFPI Entry Points
*
***********************************************************/
int
onlp_sfpi_init(void)
{
/* Called at initialization time */
return ONLP_STATUS_OK;
}
int
onlp_sfpi_bitmap_get(onlp_sfp_bitmap_t* bmap)
{
int p;
int start_port, end_port;
if(platform_id == PLATFORM_ID_DELTA_AG7648_R0)
{
start_port = SFP_PLUS_MIN_PORT;
end_port = QSFP_MAX_PORT;
}
else /*reserved*/
{
AIM_LOG_ERROR("The platform id %d is invalid \r\n", platform_id);
return ONLP_STATUS_E_UNSUPPORTED;
}
for(p = start_port; p <=end_port; p++) {
AIM_BITMAP_SET(bmap, p);
}
return ONLP_STATUS_OK;
}
int
onlp_sfpi_is_present(int port)
{
/*
* Return 1 if present.
* Return 0 if not present.
* Return < 0 if error.
*/
int present,r_data;
if((port >= SFP_PLUS_MIN_PORT) && (port <= QSFP_MAX_PORT)){
r_data=i2c_devname_read_byte(gPortCtrl[port - 1].cpldName, gPortCtrl[port - 1].presentReg);
}
else{
AIM_LOG_ERROR("The port %d is invalid \r\n", port);
return ONLP_STATUS_E_UNSUPPORTED;
}
if(r_data<0){
AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n", port);
return ONLP_STATUS_E_INTERNAL;
}
r_data = (~r_data) & 0xFF;
present = (r_data >> gPortCtrl[port - 1].presentRegBit) & 0x1;
return present;
}
int
onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst)
{
int status;
int port, i = 0;
uint64_t presence_all=0;
AIM_BITMAP_CLR_ALL(dst);
if(platform_id == PLATFORM_ID_DELTA_AG7648_R0)
{
port = 1;
}
else{
AIM_LOG_ERROR("The platform id %d is invalid \r\n", platform_id);
return ONLP_STATUS_E_UNSUPPORTED;
}
/*read 8 ports present status once*/
for (i = port; i <= QSFP_MAX_PORT;)
{
/*
AIM_LOG_ERROR("port %d, cpldname %s, reg %d\r\n", i, gPortCtrl[i - 1].cpldName, \
gPortCtrl[i - 1].presentReg);
*/
status = i2c_devname_read_byte(gPortCtrl[i - 1].cpldName, gPortCtrl[i - 1].presentReg);
if(status<0){
AIM_LOG_ERROR("Unable to read presence from the port %d to %d value(status %d) \r\n", i, i + 8, status);
return ONLP_STATUS_E_INTERNAL;
}
status = ~(status) & 0xFF;
presence_all |= ((uint64_t)(status)) << (((i - 1)/ 8) * 8);
i += 8;
}
/* Populate bitmap */
for(i = port; presence_all; i++) {
AIM_BITMAP_MOD(dst, i, (presence_all & 1));
presence_all >>= 1;
}
return ONLP_STATUS_OK;
}
int
onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst)
{
int status;
int port,i = 0;
uint64_t rx_los_all;
if(platform_id == PLATFORM_ID_DELTA_AG7648_R0)
{
port = 1;
}
else{
AIM_LOG_ERROR("The platform id %d is invalid \r\n", platform_id);
return ONLP_STATUS_E_UNSUPPORTED;
}
/*read 8 ports present status once*/
for (i = port; i <= QSFP_MAX_PORT;)
{
status = i2c_devname_read_byte(gPortCtrl[i - 1].cpldName, gPortCtrl[i - 1].rxLosReg);
if(status<0){
AIM_LOG_ERROR("Unable to read rx los from the port %d to %d value. \r\n", i, i + 8);
return ONLP_STATUS_E_INTERNAL;
}
status = ~(status) & 0xFF;
rx_los_all |= status << (((i - 1)/ 8) * 8);
i += 8;
}
/* Populate bitmap */
for(i = port; rx_los_all; i++) {
AIM_BITMAP_MOD(dst, i, (rx_los_all & 1));
rx_los_all >>= 1;
}
return ONLP_STATUS_OK;
}
int
onlp_sfpi_eeprom_read(int port, uint8_t data[256])
{
/*
* Read the SFP eeprom into data[]
*
* Return MISSING if SFP is missing.
* Return OK if eeprom is read
*/
int i;//,r_data,re_cnt;
char sfp_name[32];
//int i,re_cnt;uint8_t r_data;
memset(data, 0, 256);
memset(sfp_name, 0x0, sizeof(sfp_name));
if (port < SFP_PLUS_MIN_PORT || port > QSFP_MAX_PORT)
{
AIM_LOG_ERROR("port %d is not invalid\r\n", port);
return ONLP_STATUS_E_INVALID;
}
if (onlp_sfpi_is_present(port) <= 0)
{
AIM_LOG_WARN("port %d is note present or error\r\n", port);
return ONLP_STATUS_E_MISSING;
}
if (port <= SFP_PLUS_MAX_PORT)
sprintf(sfp_name, "SFP%d", port);
else
sprintf(sfp_name, "QSFP%d", port);
for(i=0;i<8;i++){
if (i2c_devname_read_block(sfp_name, (32*i), (char*)(data+32*i), 32) < 0)
{
AIM_LOG_ERROR("Unable to read the port %d eeprom\r\n", port);
return ONLP_STATUS_E_INTERNAL;
}
}
return ONLP_STATUS_OK;
}
int
onlp_sfpi_dom_read(int port, uint8_t data[256])
{
return onlp_sfpi_eeprom_read( port, data);
}
int
onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value)
{
/*value is 1 if the tx disable
value is 0 if the tx enable
*/
int rc,r_data,dis_value,present;
if (port < SFP_PLUS_MIN_PORT || port > QSFP_MAX_PORT)
{
AIM_LOG_ERROR("port %d is not invalid\r\n", port);
return ONLP_STATUS_E_INVALID;
}
present=onlp_sfpi_is_present(port);
if(present <= 0){
AIM_LOG_INFO("The port %d is not present and can not set tx disable\r\n",port);
return ONLP_STATUS_E_UNSUPPORTED;
}
r_data = i2c_devname_read_byte(gPortCtrl[port - 1].cpldName, gPortCtrl[port - 1].txDisableReg);
if(r_data<0){
AIM_LOG_INFO("Unable to read sfp tx disable reg value\r\n");
return ONLP_STATUS_E_INTERNAL;
}
r_data &= ~(0x1 << gPortCtrl[port - 1].txDisableReg);
dis_value = value << gPortCtrl[port - 1].txDisableReg;
dis_value |= r_data;
switch(control)
{
case ONLP_SFP_CONTROL_TX_DISABLE:
{
rc = i2c_devname_write_byte(gPortCtrl[port - 1].cpldName, gPortCtrl[port - 1].txDisableReg, dis_value);
if (rc<0) {
AIM_LOG_ERROR("Unable to set tx_disable status to port(%d)\r\n", port);
return ONLP_STATUS_E_INTERNAL;
}
break;
}
default:
return ONLP_STATUS_E_UNSUPPORTED;
}
return ONLP_STATUS_OK;
}
int
onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value)
{
int r_data,present;
if (port < SFP_PLUS_MIN_PORT || port > QSFP_MAX_PORT)
{
AIM_LOG_ERROR("port %d is not invalid\r\n", port);
return ONLP_STATUS_E_INVALID;
}
present=onlp_sfpi_is_present(port);
if(present <= 0){
AIM_LOG_INFO("The port %d is not present\r\n",port);
return ONLP_STATUS_E_UNSUPPORTED;
}
switch(control)
{
case ONLP_SFP_CONTROL_RX_LOS:
{
r_data=i2c_devname_read_byte(gPortCtrl[port - 1].cpldName, gPortCtrl[port - 1].rxLosReg);
if (r_data<0) {
AIM_LOG_ERROR("Unable to read rx_los status from port(%d)\r\n", port);
return ONLP_STATUS_E_INTERNAL;
}
r_data &= (0x1 << gPortCtrl[port - 1].rxLosRegBit);
*value = (r_data >> gPortCtrl[port - 1].rxLosRegBit);
break;
}
case ONLP_SFP_CONTROL_TX_DISABLE:
{
r_data=i2c_devname_read_byte(gPortCtrl[port - 1].cpldName, gPortCtrl[port - 1].txDisableReg);
if (r_data<0) {
AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d)\r\n", port);
return ONLP_STATUS_E_INTERNAL;
}
r_data &= (0x1 << gPortCtrl[port - 1].txDisableRegBit);
*value = (r_data >> gPortCtrl[port - 1].txDisableRegBit);
break;
}
default:
return ONLP_STATUS_E_UNSUPPORTED;
}
return ONLP_STATUS_OK;
}
int
onlp_sfpi_denit(void)
{
return ONLP_STATUS_OK;
}

View File

@@ -0,0 +1,293 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014, 2015 Big Switch Networks, Inc.
* Copyright 2016 Accton Technology Corporation.
* Copyright 2017 Delta Networks, Inc
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <onlplib/file.h>
#include <onlp/platformi/sysi.h>
#include <onlp/platformi/ledi.h>
#include <onlp/platformi/thermali.h>
#include <onlp/platformi/fani.h>
#include <onlp/platformi/psui.h>
#include "x86_64_delta_ag7648_int.h"
#include "x86_64_delta_ag7648_log.h"
#include "platform_lib.h"
#include "x86_64_delta_i2c.h"
platform_id_t platform_id = PLATFORM_ID_UNKNOWN;
#define ONIE_PLATFORM_NAME "x86-64-delta-ag7648-r0"
const char*
onlp_sysi_platform_get(void)
{
enum ag7648_product_id pid = get_product_id();
if (pid == PID_AG7648)
return "x86-64-delta-ag7648";
else
return "unknow";
}
int
onlp_sysi_platform_set(const char* platform)
{
if(strstr(platform,"x86-64-delta-ag7648-r0")) {
platform_id = PLATFORM_ID_DELTA_AG7648_R0;
return ONLP_STATUS_OK;
}
AIM_LOG_ERROR("No support for platform '%s'", platform);
return ONLP_STATUS_E_UNSUPPORTED;
}
int
onlp_sysi_platform_info_get(onlp_platform_info_t* pi)
{
int v;
v = i2c_devname_read_byte("SYSCPLD", 0X0);
pi->cpld_versions = aim_fstrdup("%d", v & 0xf);
return 0;
}
int
onlp_sysi_onie_data_get(uint8_t** data, int* size)
{
uint8_t* rdata = aim_zmalloc(256);
int i,re_cnt;
for(i=0;i<8;i++){
re_cnt=3;
while(re_cnt){
if (i2c_devname_read_block("ID_EEPROM", i * 32, (char *)(rdata + i * 32), 32) < 0)
{
re_cnt--;
continue;
}
break;
}
if(re_cnt==0){
AIM_LOG_ERROR("Unable to read the %d reg \r\n",i);
return ONLP_STATUS_E_INTERNAL;
}
}
*data = rdata;
return ONLP_STATUS_OK;
}
void
onlp_sysi_onie_data_free(uint8_t* data)
{
aim_free(data);
}
int
onlp_sysi_oids_get(onlp_oid_t* table, int max)
{
int i;
onlp_oid_t* e = table;
memset(table, 0, max*sizeof(onlp_oid_t));
/* 1 Thermal sensors on the chassis */
for (i = 1; i <= CHASSIS_THERMAL_COUNT; i++) {
*e++ = ONLP_THERMAL_ID_CREATE(i);
}
/* LEDs on the chassis */
for (i = 1; i <= chassis_led_count(); i++) {
*e++ = ONLP_LED_ID_CREATE(i);
}
/* 1 Fans on the chassis */
for (i = 1; i <= chassis_fan_count(); i++) {
*e++ = ONLP_FAN_ID_CREATE(i);
}
/* 2 PSUs on the chassis */
for (i = 1; i <= CHASSIS_PSU_COUNT; i++) {
*e++ = ONLP_PSU_ID_CREATE(i);
}
return 0;
}
int
onlp_sysi_platform_manage_fans(void)
{
int rc;
onlp_thermal_info_t ti2, ti3, ti4;
int mtemp=0;
int new_rpm=0;
if (chassis_fan_count() == 0) {
return ONLP_STATUS_E_UNSUPPORTED;
}
/* Get temperature */
/*rc = onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(1), &ti1);
if (rc != ONLP_STATUS_OK) {
return rc;
}*/
rc = onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(2), &ti2);
if (rc != ONLP_STATUS_OK) {
return rc;
}
rc = onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(3), &ti3);
if (rc != ONLP_STATUS_OK) {
return rc;
}
rc = onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(4), &ti4);
if (rc != ONLP_STATUS_OK) {
return rc;
}
mtemp=(ti2.mcelsius+ti3.mcelsius + ti4.mcelsius) / 3;
DEBUG_PRINT("mtemp %d\n", mtemp);
/* Bring fan speed according the temp
*/
if(mtemp<25000)
new_rpm=FAN_IDLE_RPM;
else if((mtemp>=30000)&&(mtemp<40000))
new_rpm=FAN_LEVEL1_RPM;
else if((mtemp>=45000)&&(mtemp<55000))
new_rpm=FAN_LEVEL2_RPM;
else if((mtemp>=60000)&&(mtemp<75000))
new_rpm=FAN_LEVEL3_RPM;
else if(mtemp>=80000)
new_rpm=FAN_LEVEL4_RPM;
else{
return ONLP_STATUS_OK;
}
onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(1),new_rpm);
onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(2),new_rpm);
onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(3),new_rpm);
onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(4),new_rpm);
onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(5),new_rpm);
onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(6),new_rpm);
return ONLP_STATUS_OK;
}
int
onlp_sysi_platform_manage_leds(void)
{
int i,tray_i,rc;
onlp_fan_info_t info;
onlp_led_mode_t fan_new_mode;
onlp_led_mode_t fan_tray_new_mode[3];
onlp_psu_info_t psu;
onlp_led_mode_t psu_new_mode;
onlp_led_mode_t sys_new_mode;
onlp_led_mode_t locator_new_mode;
/*fan led */
/*fan led */
for(tray_i=0;tray_i<3;tray_i++){
for(i=CHASSIS_FAN_COUNT-2*tray_i;i>=CHASSIS_FAN_COUNT-2*tray_i-1;i--){
rc=onlp_fani_info_get(ONLP_FAN_ID_CREATE(i), &info);
if ((rc != ONLP_STATUS_OK) ||((info.status&0x1)!=1)){
fan_tray_new_mode[tray_i]=ONLP_LED_MODE_OFF;
goto tray_next;
}
else{
if((info.status&0x2)==1){
fan_tray_new_mode[tray_i]=ONLP_LED_MODE_YELLOW;
goto tray_next;
}
}
}
fan_tray_new_mode[tray_i]=ONLP_LED_MODE_GREEN;
tray_next: continue;
}
onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_FAN_TRAY0),fan_tray_new_mode[0]);
onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_FAN_TRAY1),fan_tray_new_mode[1]);
onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_FAN_TRAY2),fan_tray_new_mode[2]);
if((fan_tray_new_mode[0]==ONLP_LED_MODE_GREEN)&&(fan_tray_new_mode[1]==ONLP_LED_MODE_GREEN)&&
(fan_tray_new_mode[2]==ONLP_LED_MODE_GREEN))
fan_new_mode=ONLP_LED_MODE_GREEN;
else if((fan_tray_new_mode[0]==ONLP_LED_MODE_OFF)||(fan_tray_new_mode[1]==ONLP_LED_MODE_OFF)||
(fan_tray_new_mode[2]==ONLP_LED_MODE_OFF))
fan_new_mode=ONLP_LED_MODE_YELLOW;
else
fan_new_mode=ONLP_LED_MODE_YELLOW_BLINKING;
onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_FAN),fan_new_mode);
/*psu1 and psu2 led */
for(i=1;i<=CHASSIS_PSU_COUNT;i++){
rc=onlp_psui_info_get(ONLP_PSU_ID_CREATE(i),&psu);
if (rc != ONLP_STATUS_OK) {
continue;
}
if((psu.status&0x1)&&!(psu.status&0x2)){
psu_new_mode=ONLP_LED_MODE_GREEN;
goto sys_led;
}
}
psu_new_mode=ONLP_LED_MODE_YELLOW_BLINKING;
sys_led :
onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_POWER),psu_new_mode);
//sys led ----------------
if((fan_new_mode!=ONLP_LED_MODE_GREEN)||(psu_new_mode!=ONLP_LED_MODE_GREEN))
sys_new_mode=ONLP_LED_MODE_YELLOW_BLINKING;
else
sys_new_mode=ONLP_LED_MODE_GREEN;
onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_SYS),sys_new_mode);
locator_new_mode=ONLP_LED_MODE_GREEN;
onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_LOCATOR),locator_new_mode);
return ONLP_STATUS_OK;
}

View File

@@ -0,0 +1,150 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014, 2015 Big Switch Networks, Inc.
* Copyright 2016 Accton Technology Corporation.
* Copyright 2017 Delta Networks, Inc
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
* Thermal Sensor Platform Implementation.
*
***********************************************************/
#include <unistd.h>
#include <onlplib/mmap.h>
#include <onlplib/file.h>
#include <onlp/platformi/thermali.h>
#include <fcntl.h>
#include "platform_lib.h"
#include "x86_64_delta_ag7648_log.h"
#include <stdio.h>
#define prefix_path "/sys/bus/i2c/devices/"
#define LOCAL_DEBUG 0
#define VALIDATE(_id) \
do { \
if(!ONLP_OID_IS_THERMAL(_id)) { \
return ONLP_STATUS_E_INVALID; \
} \
} while(0)
#define OPEN_READ_FILE(fd,fullpath,data,nbytes,len) \
DEBUG_PRINT("[Debug][%s][%d][openfile: %s]\n", __FUNCTION__, __LINE__, fullpath); \
if ((fd = open(fullpath, O_RDONLY)) == -1) \
return ONLP_STATUS_E_INTERNAL; \
if ((len = read(fd, r_data, nbytes)) <= 0){ \
close(fd); \
return ONLP_STATUS_E_INTERNAL;} \
DEBUG_PRINT("[Debug][%s][%d][read data: %s]\n", __FUNCTION__, __LINE__, r_data); \
if (close(fd) == -1) \
return ONLP_STATUS_E_INTERNAL
enum onlp_thermal_id
{
THERMAL_RESERVED = 0,
THERMAL_1_CLOSE_TO_CPU,
THERMAL_1_CLOSE_TO_MAC,
THERMAL_2_CLOSE_TO_PHY_SFP_PLUS,
THERMAL_3_CLOSE_TO_PHY_QSFP,
THERMAL_1_ON_PSU1,
THERMAL_1_ON_PSU2,
};
static char* last_path[] = /* must map with onlp_thermal_id */
{
"reserved",
"2-004d/hwmon/hwmon1/temp1_input",
"3-004c/hwmon/hwmon2/temp1_input",
"3-004d/hwmon/hwmon3/temp1_input",
"3-004e/hwmon/hwmon4/temp1_input",
"4-0058/psu_temp1_input",
"5-0058/psu_temp1_input",
};
/* Static values */
static onlp_thermal_info_t linfo[] = {
{ }, /* Not used */
{ { ONLP_THERMAL_ID_CREATE(THERMAL_1_CLOSE_TO_CPU), "Thermal Sensor 1- close to cpu", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_1_CLOSE_TO_MAC), "Thermal Sensor 1- close to mac", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_2_CLOSE_TO_PHY_SFP_PLUS), "Thermal Sensor 2- close to sfp+ phy", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_3_CLOSE_TO_PHY_QSFP), "Thermal Sensor 2- close to qsfp phy", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_1_ON_PSU1), "PSU-1 Thermal Sensor 1", ONLP_PSU_ID_CREATE(1)},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_1_ON_PSU2), "PSU-2 Thermal Sensor 1", ONLP_PSU_ID_CREATE(2)},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
}
};
/*
* This will be called to intiialize the thermali subsystem.
*/
int
onlp_thermali_init(void)
{
return ONLP_STATUS_OK;
}
/*
* Retrieve the information structure for the given thermal OID.
*
* If the OID is invalid, return ONLP_E_STATUS_INVALID.
* If an unexpected error occurs, return ONLP_E_STATUS_INTERNAL.
* Otherwise, return ONLP_STATUS_OK with the OID's information.
*
* Note -- it is expected that you fill out the information
* structure even if the sensor described by the OID is not present.
*/
int
onlp_thermali_info_get(onlp_oid_t id, onlp_thermal_info_t* info)
{
int fd, len, nbytes = 10, temp_base=1, local_id;
char r_data[10] = {0};
char fullpath[50] = {0};
VALIDATE(id);
local_id = ONLP_OID_ID_GET(id);
DEBUG_PRINT("\n[Debug][%s][%d][local_id: %d]", __FUNCTION__, __LINE__, local_id);
/* Set the onlp_oid_hdr_t and capabilities */
*info = linfo[local_id];
/* get fullpath */
sprintf(fullpath, "%s%s", prefix_path, last_path[local_id]);
OPEN_READ_FILE(fd, fullpath, r_data, nbytes, len);
info->mcelsius = atoi(r_data) / temp_base;
DEBUG_PRINT("\n[Debug][%s][%d][save data: %d]\n", __FUNCTION__, __LINE__, info->mcelsius);
return ONLP_STATUS_OK;
}

View File

@@ -0,0 +1,81 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_delta_ag7648/x86_64_delta_ag7648_config.h>
/* <auto.start.cdefs(X86_64_DELTA_AG7648_CONFIG_HEADER).source> */
#define __x86_64_delta_ag7648_config_STRINGIFY_NAME(_x) #_x
#define __x86_64_delta_ag7648_config_STRINGIFY_VALUE(_x) __x86_64_delta_ag7648_config_STRINGIFY_NAME(_x)
x86_64_delta_ag7648_config_settings_t x86_64_delta_ag7648_config_settings[] =
{
#ifdef X86_64_DELTA_AG7648_CONFIG_INCLUDE_LOGGING
{ __x86_64_delta_ag7648_config_STRINGIFY_NAME(X86_64_DELTA_AG7648_CONFIG_INCLUDE_LOGGING), __x86_64_delta_ag7648_config_STRINGIFY_VALUE(X86_64_DELTA_AG7648_CONFIG_INCLUDE_LOGGING) },
#else
{ X86_64_DELTA_AG7648_CONFIG_INCLUDE_LOGGING(__x86_64_delta_ag7648_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AG7648_CONFIG_LOG_OPTIONS_DEFAULT
{ __x86_64_delta_ag7648_config_STRINGIFY_NAME(X86_64_DELTA_AG7648_CONFIG_LOG_OPTIONS_DEFAULT), __x86_64_delta_ag7648_config_STRINGIFY_VALUE(X86_64_DELTA_AG7648_CONFIG_LOG_OPTIONS_DEFAULT) },
#else
{ X86_64_DELTA_AG7648_CONFIG_LOG_OPTIONS_DEFAULT(__x86_64_delta_ag7648_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AG7648_CONFIG_LOG_BITS_DEFAULT
{ __x86_64_delta_ag7648_config_STRINGIFY_NAME(X86_64_DELTA_AG7648_CONFIG_LOG_BITS_DEFAULT), __x86_64_delta_ag7648_config_STRINGIFY_VALUE(X86_64_DELTA_AG7648_CONFIG_LOG_BITS_DEFAULT) },
#else
{ X86_64_DELTA_AG7648_CONFIG_LOG_BITS_DEFAULT(__x86_64_delta_ag7648_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AG7648_CONFIG_LOG_CUSTOM_BITS_DEFAULT
{ __x86_64_delta_ag7648_config_STRINGIFY_NAME(X86_64_DELTA_AG7648_CONFIG_LOG_CUSTOM_BITS_DEFAULT), __x86_64_delta_ag7648_config_STRINGIFY_VALUE(X86_64_DELTA_AG7648_CONFIG_LOG_CUSTOM_BITS_DEFAULT) },
#else
{ X86_64_DELTA_AG7648_CONFIG_LOG_CUSTOM_BITS_DEFAULT(__x86_64_delta_ag7648_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AG7648_CONFIG_PORTING_STDLIB
{ __x86_64_delta_ag7648_config_STRINGIFY_NAME(X86_64_DELTA_AG7648_CONFIG_PORTING_STDLIB), __x86_64_delta_ag7648_config_STRINGIFY_VALUE(X86_64_DELTA_AG7648_CONFIG_PORTING_STDLIB) },
#else
{ X86_64_DELTA_AG7648_CONFIG_PORTING_STDLIB(__x86_64_delta_ag7648_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AG7648_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS
{ __x86_64_delta_ag7648_config_STRINGIFY_NAME(X86_64_DELTA_AG7648_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS), __x86_64_delta_ag7648_config_STRINGIFY_VALUE(X86_64_DELTA_AG7648_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS) },
#else
{ X86_64_DELTA_AG7648_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS(__x86_64_delta_ag7648_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AG7648_CONFIG_INCLUDE_UCLI
{ __x86_64_delta_ag7648_config_STRINGIFY_NAME(X86_64_DELTA_AG7648_CONFIG_INCLUDE_UCLI), __x86_64_delta_ag7648_config_STRINGIFY_VALUE(X86_64_DELTA_AG7648_CONFIG_INCLUDE_UCLI) },
#else
{ X86_64_DELTA_AG7648_CONFIG_INCLUDE_UCLI(__x86_64_delta_ag7648_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AG7648_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION
{ __x86_64_delta_ag7648_config_STRINGIFY_NAME(X86_64_DELTA_AG7648_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION), __x86_64_delta_ag7648_config_STRINGIFY_VALUE(X86_64_DELTA_AG7648_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION) },
#else
{ X86_64_DELTA_AG7648_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION(__x86_64_delta_ag7648_config_STRINGIFY_NAME), "__undefined__" },
#endif
{ NULL, NULL }
};
#undef __x86_64_delta_ag7648_config_STRINGIFY_VALUE
#undef __x86_64_delta_ag7648_config_STRINGIFY_NAME
const char*
x86_64_delta_ag7648_config_lookup(const char* setting)
{
int i;
for(i = 0; x86_64_delta_ag7648_config_settings[i].name; i++) {
if(strcmp(x86_64_delta_ag7648_config_settings[i].name, setting)) {
return x86_64_delta_ag7648_config_settings[i].value;
}
}
return NULL;
}
int
x86_64_delta_ag7648_config_show(struct aim_pvs_s* pvs)
{
int i;
for(i = 0; x86_64_delta_ag7648_config_settings[i].name; i++) {
aim_printf(pvs, "%s = %s\n", x86_64_delta_ag7648_config_settings[i].name, x86_64_delta_ag7648_config_settings[i].value);
}
return i;
}
/* <auto.end.cdefs(X86_64_DELTA_AG7648_CONFIG_HEADER).source> */

View File

@@ -0,0 +1,10 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_delta_ag7648/x86_64_delta_ag7648_config.h>
/* <--auto.start.enum(ALL).source> */
/* <auto.end.enum(ALL).source> */

View File

@@ -0,0 +1,12 @@
/**************************************************************************//**
*
* x86_64_delta_ag7648 Internal Header
*
*****************************************************************************/
#ifndef __x86_64_delta_ag7648_INT_H__
#define __x86_64_delta_ag7648_INT_H__
#include <x86_64_delta_ag7648/x86_64_delta_ag7648_config.h>
#endif /* __x86_64_delta_ag7648_INT_H__ */

View File

@@ -0,0 +1,18 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_delta_ag7648/x86_64_delta_ag7648_config.h>
#include "x86_64_delta_ag7648_log.h"
/*
* x86_64_delta_ag7648 log struct.
*/
AIM_LOG_STRUCT_DEFINE(
X86_64_DELTA_AG7648_CONFIG_LOG_OPTIONS_DEFAULT,
X86_64_DELTA_AG7648_CONFIG_LOG_BITS_DEFAULT,
NULL, /* Custom log map */
X86_64_DELTA_AG7648_CONFIG_LOG_CUSTOM_BITS_DEFAULT
);

View File

@@ -0,0 +1,12 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#ifndef __x86_64_delta_ag7648_LOG_H__
#define __x86_64_delta_ag7648_LOG_H__
#define AIM_LOG_MODULE_NAME x86_64_delta_ag7648
#include <AIM/aim_log.h>
#endif /* __x86_64_delta_ag7648_LOG_H__ */

View File

@@ -0,0 +1,24 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_delta_ag7648/x86_64_delta_ag7648_config.h>
#include "x86_64_delta_ag7648_log.h"
static int
datatypes_init__(void)
{
#define x86_64_delta_ag7648_ENUMERATION_ENTRY(_enum_name, _desc) AIM_DATATYPE_MAP_REGISTER(_enum_name, _enum_name##_map, _desc, AIM_LOG_INTERNAL);
#include <x86_64_delta_ag7648/x86_64_delta_ag7648.x>
return 0;
}
void __x86_64_delta_ag7648_module_init__(void)
{
AIM_LOG_STRUCT_REGISTER();
datatypes_init__();
}
int __onlp_platform_version__ = 1;

View File

@@ -0,0 +1,50 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_delta_ag7648/x86_64_delta_ag7648_config.h>
#if X86_64_DELTA_AG7648_CONFIG_INCLUDE_UCLI == 1
#include <uCli/ucli.h>
#include <uCli/ucli_argparse.h>
#include <uCli/ucli_handler_macros.h>
static ucli_status_t
x86_64_delta_ag7648_ucli_ucli__config__(ucli_context_t* uc)
{
UCLI_HANDLER_MACRO_MODULE_CONFIG(x86_64_delta_ag7648)
}
/* <auto.ucli.handlers.start> */
/* <auto.ucli.handlers.end> */
static ucli_module_t
x86_64_delta_ag7648_ucli_module__ =
{
"x86_64_delta_ag7648_ucli",
NULL,
x86_64_delta_ag7648_ucli_ucli_handlers__,
NULL,
NULL,
};
ucli_node_t*
x86_64_delta_ag7648_ucli_node_create(void)
{
ucli_node_t* n;
ucli_module_init(&x86_64_delta_ag7648_ucli_module__);
n = ucli_node_create("x86_64_delta_ag7648", NULL, &x86_64_delta_ag7648_ucli_module__);
ucli_node_subnode_add(n, ucli_module_log_node_create("x86_64_delta_ag7648"));
return n;
}
#else
void*
x86_64_delta_ag7648_ucli_node_create(void)
{
return NULL;
}
#endif

View File

@@ -0,0 +1,396 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014, 2015 Big Switch Networks, Inc.
* Copyright 2016 Accton Technology Corporation.
* Copyright 2017 Delta Networks, Inc
* Copyright 2017 Delta Networks, Inc
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************/
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include "x86_64_delta_ag7648_log.h"
#include "x86_64_delta_i2c.h"
#include "x86_64_delta_i2c_dev.h"
struct i2c_device_info i2c_device_list[]={
{"RTC",0X0,0X69},
{"TMP1_CLOSE_TO_CPU",0X2,0X4d},
{"TMP1_CLOSE_TO_MAC",0X3,0X4c},
{"TMP2_CLOSE_TO_SFP_PLUS",0X3,0X4d},
{"TMP3_CLOSE_TO_QSFP",0X3,0X4E},
{"SYSCPLD",0X2,0X31},
{"MASTERCPLD",0X2,0X32},
{"SLAVECPLD",0X2,0X33},
{"FAN1EEPROM",0X3,0X51},
{"FAN2EEPROM",0X3,0X52},
{"FAN3EEPROM",0X3,0X53},
{"FANCTRL1",0X3,0X2A},
{"FANCTRL2",0X3,0X29},
{"CURT_MONTOR",0X1,0X40},
{"ID_EEPROM",0X2,0X53},
{"SFP1",0XA,0X50},
{"SFP2",0XB,0X50},
{"SFP3",0XC,0X50},
{"SFP4",0XD,0X50},
{"SFP5",0XE,0X50},
{"SFP6",0XF,0X50},
{"SFP7",0X10,0X50},
{"SFP8",0X11,0X50},
{"SFP9",0X12,0X50},
{"SFP10",0X13,0X50},
{"SFP11",0X14,0X50},
{"SFP12",0X15,0X50},
{"SFP13",0X16,0X50},
{"SFP14",0X17,0X50},
{"SFP15",0X18,0X50},
{"SFP16",0X19,0X50},
{"SFP17",0X1A,0X50},
{"SFP18",0X1B,0X50},
{"SFP19",0X1C,0X50},
{"SFP20",0X1D,0X50},
{"SFP21",0X1E,0X50},
{"SFP22",0X1F,0X50},
{"SFP23",0X20,0X50},
{"SFP24",0X21,0X50},
{"SFP25",0X22,0X50},
{"SFP26",0X23,0X50},
{"SFP27",0X24,0X50},
{"SFP28",0X25,0X50},
{"SFP29",0X26,0X50},
{"SFP30",0X27,0X50},
{"SFP31",0X28,0X50},
{"SFP32",0X29,0X50},
{"SFP33",0X2A,0X50},
{"SFP34",0X2B,0X50},
{"SFP35",0X2C,0X50},
{"SFP36",0X2D,0X50},
{"SFP37",0X2E,0X50},
{"SFP38",0X2F,0X50},
{"SFP39",0X30,0X50},
{"SFP40",0X31,0X50},
{"SFP41",0X32,0X50},
{"SFP42",0X33,0X50},
{"SFP43",0X34,0X50},
{"SFP44",0X35,0X50},
{"SFP45",0X36,0X50},
{"SFP46",0X37,0X50},
{"SFP47",0X38,0X50},
{"SFP48",0X39,0X50},
{"QSFP49",0X3A,0X50},
{"QSFP50",0X3B,0X50},
{"QSFP51",0X3C,0X50},
{"QSFP52",0X3D,0X50},
{"QSFP53",0X3E,0X50},
{"QSFP54",0X3F,0X50},
// -------------------------
{"PSU1_PMBUS",0X6,0X58},
{"PSU2_PMBUS",0X6,0X59},
{"PSU1_EEPROM",0X6,0X50},
{"PSU2_EEPROM",0X6,0X51},
{NULL, -1,-1},
};
#define I2C_DATA_B 1
#define I2C_DATA_W 2
#define I2C_DATA_C 3
#define I2C_DATA_QUICK 4
static pthread_mutex_t i2c_mutex = PTHREAD_MUTEX_INITIALIZER;
void I2C_PROTECT (void)
{
pthread_mutex_lock (&i2c_mutex);
}
void I2C_UNPROTECT (void)
{
pthread_mutex_unlock (&i2c_mutex);
}
static int open_i2cbus_dev(int i2cbus, char *filename, int quiet)
{
int file;
sprintf(filename, "/dev/i2c-%d", i2cbus);
file = open(filename, O_RDWR);
if (file < 0 && !quiet) {
if (errno == ENOENT) {
fprintf(stderr, "Error: Could not open file "
"`/dev/i2c-%d: %s'\n",i2cbus, strerror(ENOENT));
} else {
fprintf(stderr, "Error: Could not open file "
"`%s': %s\n", filename, strerror(errno));
if (errno == EACCES)
fprintf(stderr, "Run as root?\n");
}
}
return file;
}
static int set_slave_addr(int file, int address, int force)
{
/* hack */
force = 1; /* force always, it will break th i2c driver's behave */
/* With force, let the user read from/write to the registers
even when a driver is also running */
if (ioctl(file, force ? I2C_SLAVE_FORCE : I2C_SLAVE, address) < 0) {
if (errno != EBUSY) {
fprintf(stderr,
"Error: Could not set address to 0x%02x: %s\n",
address, strerror(errno));
return -errno;
}
}
return 0;
}
static int i2c_dev_read (int i2cbus, int dev, int reg, int mode)
{
int file;
char filename[20];
int force = 0;
int res = 0;
file = open_i2cbus_dev(i2cbus, filename, 0);
if (file < 0) return -1;
if (set_slave_addr(file, dev, force))return -1;
switch (mode) {
case I2C_DATA_W:
res = i2c_smbus_read_word_data(file, reg);
break;
case I2C_DATA_C:
if (reg >= 0) {
res = i2c_smbus_write_byte(file, reg);
if (res < 0) break;
}
res = i2c_smbus_read_byte(file);
break;
default:
res = i2c_smbus_read_byte_data(file, reg);
break;
}
close(file);
return res;
}
static int i2c_dev_write (int i2cbus, int dev, int reg, int value, int mode)
{
int file;
char filename[20];
int force = 0;
int res = 0;
file = open_i2cbus_dev(i2cbus, filename, 0);
if (file < 0) return -1;
if (set_slave_addr(file, dev, force)) return -1;
switch (mode) {
case I2C_DATA_W:
res = i2c_smbus_write_word_data(file, reg, value);
break;
case I2C_DATA_C:
res = i2c_smbus_write_byte (file, reg);
break;
case I2C_DATA_QUICK:
res = i2c_smbus_write_quick(file, I2C_SMBUS_WRITE);
break;
default:
res = i2c_smbus_write_byte_data(file, reg, value);
break;
}
close(file);
usleep (5000);
return res;
}
static int i2c_block_read (int i2cbus, int dev, int reg, char *buff, int buff_len)
{
int file;
char filename[20];
int force = 0;
int res = 0;
file = open_i2cbus_dev(i2cbus, filename, 0);
if (file < 0) return -1;
if (set_slave_addr(file, dev, force)) return -1;
res = i2c_smbus_read_i2c_block_data (file, reg, buff_len, (__u8 *)buff);
close(file);
return res;
}
static int i2c_block_write (int i2cbus, int dev, int reg, char *buff, int buff_len)
{
int file;
char filename[20];
int force = 0;
int res = 0;
file = open_i2cbus_dev(i2cbus, filename, 0);
if (file < 0) return -1;
if (set_slave_addr(file, dev, force)) return -1;
res = i2c_smbus_write_i2c_block_data (file, reg, buff_len, (__u8 *)buff);
close(file);
return res;
}
i2c_device_info_t *i2c_dev_find_by_name (char *name)
{
i2c_device_info_t *i2c_dev = i2c_device_list;
if (name == NULL) return NULL;
while (i2c_dev->name) {
if (strcmp (name, i2c_dev->name) == 0) break;
++ i2c_dev;
}
if (i2c_dev->name == NULL) return NULL;
return i2c_dev;
}
int i2c_devname_read_byte (char *name, int reg)
{
int ret=-1;
i2c_device_info_t *i2c_dev = i2c_dev_find_by_name (name);
if(i2c_dev==NULL) return -1;
I2C_PROTECT();
ret=i2c_dev_read (i2c_dev->i2cbus, i2c_dev->addr, reg, I2C_DATA_B);
I2C_UNPROTECT();
return ret;
}
int i2c_devname_write_byte (char *name, int reg, int value)
{
int ret=-1;
i2c_device_info_t *i2c_dev = i2c_dev_find_by_name (name);
if(i2c_dev==NULL) return -1;
I2C_PROTECT();
ret=i2c_dev_write (i2c_dev->i2cbus, i2c_dev->addr, reg, value, I2C_DATA_B);
I2C_UNPROTECT();
return ret;
}
int i2c_devname_read_word (char *name, int reg)
{
int ret=-1;
i2c_device_info_t *i2c_dev = i2c_dev_find_by_name (name);
if(i2c_dev==NULL) return -1;
I2C_PROTECT();
ret=i2c_dev_read (i2c_dev->i2cbus, i2c_dev->addr, reg, I2C_DATA_W);
I2C_UNPROTECT();
return ret;
}
int i2c_devname_write_word (char *name, int reg, int value)
{
int ret=-1;
i2c_device_info_t *i2c_dev = i2c_dev_find_by_name (name);
if(i2c_dev==NULL) return -1;
I2C_PROTECT();
ret=i2c_dev_write (i2c_dev->i2cbus, i2c_dev->addr, reg, value, I2C_DATA_W);
I2C_UNPROTECT();
return ret;
}
int i2c_devname_read_block (char *name, int reg, char *buff, int buff_size)
{
int ret = -1;
i2c_device_info_t *i2c_dev = i2c_dev_find_by_name (name);
if(i2c_dev==NULL) return -1;
I2C_PROTECT();
ret = i2c_block_read (i2c_dev->i2cbus, i2c_dev->addr, reg, buff, buff_size);
I2C_UNPROTECT();
return ret;
}
int i2c_devname_write_block (char *name, int reg, char *buff, int buff_size)
{
int ret = -1;
i2c_device_info_t *i2c_dev = i2c_dev_find_by_name (name);
if(i2c_dev==NULL) return -1;
I2C_PROTECT();
ret = i2c_block_write (i2c_dev->i2cbus, i2c_dev->addr, reg, buff, buff_size);
I2C_UNPROTECT();
return ret;
}

View File

@@ -0,0 +1,55 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014, 2015 Big Switch Networks, Inc.
* Copyright 2016 Accton Technology Corporation.
* Copyright 2017 Delta Networks, Inc
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************/
/* the i2c struct header*/
#ifndef __X86_64_DELTA_I2C_H__
#define __X86_64_DELTA_I2C_H__
#include "x86_64_delta_ag7648_log.h"
struct i2c_device_info {
/*i2c device name*/
char *name;
char i2cbus;
char addr;
};
typedef struct i2c_device_info i2c_device_info_t;
extern struct i2c_device_info i2c_device_list[];
extern int i2c_devname_read_byte(char *name, int reg);
extern int i2c_devname_write_byte(char *name, int reg, int value);
extern int i2c_devname_read_word(char *name, int reg);
extern int i2c_devname_write_word(char *name, int reg, int value);
extern int i2c_devname_read_block (char *name, int reg, char *buff, int buff_size);
extern int i2c_devname_write_block(char *name, int reg, char *buff, int buff_size);
#endif

View File

@@ -0,0 +1,209 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014, 2015 Big Switch Networks, Inc.
* Copyright 2016 Accton Technology Corporation.
* Copyright 2017 Delta Networks, Inc
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************/
#ifndef __X86_64_DELTA_I2C_DEV_H__
#define __X86_64_DELTA_I2C_DEV_H__
#include <linux/types.h>
#include <sys/ioctl.h>
#include "x86_64_delta_ag7648_log.h"
/* -- i2c.h -- */
//#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#if 0
static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command,
int size, union i2c_smbus_data *data)
{
struct i2c_smbus_ioctl_data args;
args.read_write = read_write;
args.command = command;
args.size = size;
args.data = data;
return ioctl(file,I2C_SMBUS,&args);
}
static inline __s32 i2c_smbus_write_quick(int file, __u8 value)
{
return i2c_smbus_access(file,value,0,I2C_SMBUS_QUICK,NULL);
}
static inline __s32 i2c_smbus_read_byte(int file)
{
union i2c_smbus_data data;
if (i2c_smbus_access(file,I2C_SMBUS_READ,0,I2C_SMBUS_BYTE,&data))
return -1;
else
return 0x0FF & data.byte;
}
static inline __s32 i2c_smbus_write_byte(int file, __u8 value)
{
return i2c_smbus_access(file,I2C_SMBUS_WRITE,value,
I2C_SMBUS_BYTE,NULL);
}
static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command)
{
union i2c_smbus_data data;
if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
I2C_SMBUS_BYTE_DATA,&data))
return -1;
else
return 0x0FF & data.byte;
}
static inline __s32 i2c_smbus_write_byte_data(int file, __u8 command,
__u8 value)
{
union i2c_smbus_data data;
data.byte = value;
return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
I2C_SMBUS_BYTE_DATA, &data);
}
static inline __s32 i2c_smbus_read_word_data(int file, __u8 command)
{
union i2c_smbus_data data;
if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
I2C_SMBUS_WORD_DATA,&data))
return -1;
else
return 0x0FFFF & data.word;
}
static inline __s32 i2c_smbus_write_word_data(int file, __u8 command,
__u16 value)
{
union i2c_smbus_data data;
data.word = value;
return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
I2C_SMBUS_WORD_DATA, &data);
}
static inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value)
{
union i2c_smbus_data data;
data.word = value;
if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
I2C_SMBUS_PROC_CALL,&data))
return -1;
else
return 0x0FFFF & data.word;
}
/* Returns the number of read bytes */
static inline __s32 i2c_smbus_read_block_data(int file, __u8 command,
__u8 *values)
{
union i2c_smbus_data data;
int i;
if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
I2C_SMBUS_BLOCK_DATA,&data))
return -1;
else {
for (i = 1; i <= data.block[0]; i++)
values[i-1] = data.block[i];
return data.block[0];
}
}
static inline __s32 i2c_smbus_write_block_data(int file, __u8 command,
__u8 length, const __u8 *values)
{
union i2c_smbus_data data;
int i;
if (length > 32)
length = 32;
for (i = 1; i <= length; i++)
data.block[i] = values[i-1];
data.block[0] = length;
return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
I2C_SMBUS_BLOCK_DATA, &data);
}
/* Returns the number of read bytes */
/* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
ask for less than 32 bytes, your code will only work with kernels
2.6.23 and later. */
static inline __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command,
__u8 length, __u8 *values)
{
union i2c_smbus_data data;
int i;
if (length > 32)
length = 32;
data.block[0] = length;
if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
length == 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN :
I2C_SMBUS_I2C_BLOCK_DATA,&data))
return -1;
else {
for (i = 1; i <= data.block[0]; i++)
values[i-1] = data.block[i];
return data.block[0];
}
}
static inline __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command,
__u8 length,
const __u8 *values)
{
union i2c_smbus_data data;
int i;
if (length > 32)
length = 32;
for (i = 1; i <= length; i++)
data.block[i] = values[i-1];
data.block[0] = length;
return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
I2C_SMBUS_I2C_BLOCK_BROKEN, &data);
}
/* Returns the number of read bytes */
static inline __s32 i2c_smbus_block_process_call(int file, __u8 command,
__u8 length, __u8 *values)
{
union i2c_smbus_data data;
int i;
if (length > 32)
length = 32;
for (i = 1; i <= length; i++)
data.block[i] = values[i-1];
data.block[0] = length;
if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
I2C_SMBUS_BLOCK_PROC_CALL,&data))
return -1;
else {
for (i = 1; i <= data.block[0]; i++)
values[i-1] = data.block[i];
return data.block[0];
}
}
#endif
#endif

View File

@@ -0,0 +1,13 @@
###############################################################################
#
# Inclusive Makefile for the x86_64_delta_ag7648 module.
#
# Autogenerated 2017-03-20 15:05:23.627200
#
###############################################################################
x86_64_delta_ag7648_BASEDIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
include $(x86_64_delta_ag7648_BASEDIR)module/make.mk
include $(x86_64_delta_ag7648_BASEDIR)module/auto/make.mk
include $(x86_64_delta_ag7648_BASEDIR)module/src/make.mk

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
!include $ONL_TEMPLATES/platform-config-platform.yml ARCH=amd64 VENDOR=delta BASENAME=x86-64-delta-ag7648 REVISION=r0

View File

@@ -0,0 +1,32 @@
---
######################################################################
#
# platform-config for AG7648
#
######################################################################
x86-64-delta-ag7648-r0:
grub:
serial: >-
--port=0x3f8
--speed=115200
--word=8
--parity=no
--stop=1
kernel:
<<: *kernel-3-16
args: >-
nopat
acpi=off
console=ttyS0,115200n8
##network
## interfaces:
## ma1:
## name: ~
## syspath: pci0000:00/0000:00:14.0

View File

@@ -0,0 +1,31 @@
from onl.platform.base import *
from onl.platform.delta import *
class OnlPlatform_x86_64_delta_ag7648_r0(OnlPlatformDelta):
PLATFORM='x86-64-delta-ag7648-r0'
MODEL="AG7648"
SYS_OBJECT_ID=".7648.1"
PORT_COUNT=54
PORT_CONFIG="48x10 + 6x40"
def baseconfig(self):
self.new_i2c_device('pca9547', 0x70, 1);
self.insmod('x86-64-delta-ag7648-cpld-mux-1.ko')
self.insmod('x86-64-delta-ag7648-cpld-mux-2.ko')
########### initialize I2C bus 0 ###########
self.new_i2c_devices(
[
('clock_gen', 0x69, 0),
('tmp75', 0x4d, 2),
('tmp75', 0x4c, 3),
('tmp75', 0x4d, 3),
('tmp75', 0x4e, 3),
]
)
return True