Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mdio IPC client library #11284

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions platform/broadcom/rules.dep
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ include $(PLATFORM_PATH)/one-image.dep
include $(PLATFORM_PATH)/raw-image.dep
include $(PLATFORM_PATH)/one-aboot.dep
include $(PLATFORM_PATH)/libsaithrift-dev.dep
include $(PLATFORM_PATH)/../components/libmdio-ipc-client.dep
include $(PLATFORM_PATH)/docker-syncd-brcm-dnx.dep
include $(PLATFORM_PATH)/docker-syncd-brcm-dnx-rpc.dep
include $(PLATFORM_PATH)/../components/docker-gbsyncd-credo.dep
1 change: 1 addition & 0 deletions platform/broadcom/rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ include $(PLATFORM_PATH)/one-image.mk
include $(PLATFORM_PATH)/raw-image.mk
include $(PLATFORM_PATH)/one-aboot.mk
include $(PLATFORM_PATH)/libsaithrift-dev.mk
include $(PLATFORM_PATH)/../components/libmdio-ipc-client.mk
include $(PLATFORM_PATH)/docker-syncd-brcm-dnx.mk
include $(PLATFORM_PATH)/docker-syncd-brcm-dnx-rpc.mk
include $(PLATFORM_PATH)/../components/docker-gbsyncd-credo.mk
Expand Down
10 changes: 10 additions & 0 deletions platform/components/libmdio-ipc-client.dep
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

SPATH := $($(MDIO_IPC_CLIENT_LIBRARY)_SRC_PATH)
DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/components/libmdio-ipc-client.mk platform/components/libmdio-ipc-client.dep
DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST)
DEP_FILES += $(shell git ls-files $(SPATH))

$(MDIO_IPC_CLIENT_LIBRARY)_CACHE_MODE := GIT_CONTENT_SHA
$(MDIO_IPC_CLIENT_LIBRARY)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) $(LOCAL_PAI_DEBS_PATH)
$(MDIO_IPC_CLIENT_LIBRARY)_DEP_FILES := $(DEP_FILES)

15 changes: 15 additions & 0 deletions platform/components/libmdio-ipc-client.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# MDIO IPC client library

MDIO_IPC_CLIENT_LIB_VERSION = 1.1

export MDIO_IPC_CLIENT_LIB_VERSION

MDIO_IPC_CLIENT_LIBRARY = libmdio-ipc-client_$(MDIO_IPC_CLIENT_LIB_VERSION)_amd64.deb
MDIO_IPC_CLIENT_LIBRARY_DBG = libmdio-ipc-client-dbg_$(MDIO_IPC_CLIENT_LIB_VERSION)_amd64.deb

$(MDIO_IPC_CLIENT_LIBRARY)_SRC_PATH = platform/components/libmdio-ipc-client
SONIC_DPKG_DEBS += $(MDIO_IPC_CLIENT_LIBRARY)
$(eval $(call add_derived_package,$(MDIO_IPC_CLIENT_LIBRARY),$(MDIO_IPC_CLIENT_LIBRARY_DBG)))

$(MDIO_IPC_CLIENT_LIBRARY)_DEPENDS += $(BRCM_SAI_DEV)

25 changes: 25 additions & 0 deletions platform/components/libmdio-ipc-client/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
PREFIX ?=

CC := g++
CXX := g++

CFLAGS := -Os -g -fPIC -Wall -Werror -Wno-uninitialized -Wno-format-truncation \
-I/usr/include/sai
CFLAGS += $(SONIC_COMMON_CFLAGS)
CXXFLAGS := $(CFLAGS)
LDFLAGS := $(SONIC_COMMON_LDFLAGS)

SRCS := mdio_ipc_client.cpp
OBJS := $(SRCS:.cpp=.o)

all: libmdio_ipc_client.so

$(OBJS) :%.o:%.cpp
$(CXX) -c -o $@ $^ $(CXXFLAGS)


libmdio_ipc_client.so: $(OBJS)
$(CXX) -shared -o $@ $^ $(LDFLAGS)

clean:
rm -f libmdio_ipc_client.so *.o
5 changes: 5 additions & 0 deletions platform/components/libmdio-ipc-client/debian/changelog
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
libmdio-ipc-client (1.1) unstable; urgency=low

* Initial release.

-- Jiahua Wang <jiahua.wang@broadcom.com> Fri, 18 Dec 2020 12:00:00 -0800
1 change: 1 addition & 0 deletions platform/components/libmdio-ipc-client/debian/compat
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
10
18 changes: 18 additions & 0 deletions platform/components/libmdio-ipc-client/debian/control
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Source: libmdio-ipc-client
Section: main
Priority: extra
Maintainer: Jiahua Wang <jiahua.wang@broadcom.com>
Build-Depends: debhelper (>= 9), bzip2
Standards-Version: 3.9.3

Package: libmdio-ipc-client
Architecture: amd64
Depends: ${shlibs:Depends}
Description: Package contains MDIO access library for gbsyncd

Package: libmdio-ipc-client-dbg
Architecture: any
Section: debug
Priority: extra
Depends: libmdio-ipc-client (=${binary:Version})
Description: debugging symbols for libmdio-ipc-client
46 changes: 46 additions & 0 deletions platform/components/libmdio-ipc-client/debian/rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/usr/bin/make -f

# See debhelper(7) (uncomment to enable)
# output every command that modifies files on the build system.
export DH_VERBOSE = 1

# see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/*
DPKG_EXPORT_BUILDFLAGS = 1
include /usr/share/dpkg/default.mk

# see FEATURE AREAS in dpkg-buildflags(1)
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all

# see ENVIRONMENT in dpkg-buildflags(1)
# package maintainers to append CFLAGS
#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
# package maintainers to append LDFLAGS
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed

PACKAGE_NAME := libmdio-ipc-client

# main packaging script based on dh7 syntax
%:
dh $@

build:
$(MAKE)

clean:
$(MAKE) clean

override_dh_auto_install:
dh_installdirs -p $(PACKAGE_NAME) /usr/lib
cp libmdio_ipc_client.so debian/$(PACKAGE_NAME)/usr/lib
dh_installdirs -p $(PACKAGE_NAME) /usr/include
cp mdio_ipc_client.h debian/$(PACKAGE_NAME)/usr/include
dh_auto_install --destdir=debian/$(PACKAGE_NAME)

override_dh_auto_test:

override_dh_clean:
dh_auto_clean
$(MAKE) clean

override_dh_strip:
dh_strip -p$(PACKAGE_NAME) --dbg-package=$(PACKAGE_NAME)-dbg
226 changes: 226 additions & 0 deletions platform/components/libmdio-ipc-client/mdio_ipc_client.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
/* Includes */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>

extern "C" {
#include "sai.h"
}

#define SAI_IPC_SOCK_DIR_SYNCD "/var/run/sswsyncd"
#define SAI_IPC_SOCK_DIR_HOST "/var/run/docker-syncd"
#define SAI_IPC_SOCK_FILE "mdio-ipc"
#define SAI_IPC_BUFF_SIZE 256

#define CONN_TIMEOUT 25 /* shorter than 30 sec on server side */

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

/* Global variables */

static int syncd_mdio_ipc_command(char *cmd, char *resp)
{
int fd;
ssize_t ret;
size_t len;
struct sockaddr_un saddr, caddr;
static int sock = 0;
static char path[128] = { 0 };
static time_t timeout = 0;

if (timeout < time(NULL))
{
/* It might already be timed out at the server side, reconnect ... */
if (sock > 0)
{
close(sock);
}
sock = 0;
}

if (strlen(path) == 0)
{
strcpy(path, SAI_IPC_SOCK_DIR_SYNCD);
fd = open(path, O_DIRECTORY);
if (fd < 0)
{
printf("%s: Program is not run on host\n", __func__);
strcpy(path, SAI_IPC_SOCK_DIR_HOST);
fd = open(path, O_DIRECTORY);
if (fd < 0)
{
printf("%s: Unable to open the directory for IPC\n", __func__);
return errno;
}
}
}

if (sock <= 0)
{
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0)
{
perror("socket()");
return errno;
}

caddr.sun_family = AF_UNIX;
snprintf(caddr.sun_path, sizeof(caddr.sun_path), "%s/%s.cli.%d", path, SAI_IPC_SOCK_FILE, getpid());
unlink(caddr.sun_path);
if (bind(sock, (struct sockaddr *)&caddr, sizeof(caddr)) < 0)
{
perror("bind()");
close(sock);
sock = 0;
return errno;
}

saddr.sun_family = AF_UNIX;
snprintf(saddr.sun_path, sizeof(saddr.sun_path), "%s/%s.srv", path, SAI_IPC_SOCK_FILE);
if (connect(sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0)
{
perror("connect()");
close(sock);
sock = 0;
unlink(caddr.sun_path);
return errno;
}
}

len = strlen(cmd);
ret = send(sock, cmd, len, 0);
if (ret < (ssize_t)len)
{
printf("send failed, ret=%ld, expected=%ld\n", ret, len);
close(sock);
sock = 0;
unlink(caddr.sun_path);
return -EIO;
}

ret = recv(sock, resp, SAI_IPC_BUFF_SIZE - 1, 0);
if (ret <= 0)
{
printf("recv failed, ret=%ld\n", ret);
close(sock);
sock = 0;
unlink(caddr.sun_path);
return -EIO;
}

timeout = time(NULL) + CONN_TIMEOUT;
return (int)strtol(resp, NULL, 0);
}


/* Function to read data from MDIO interface */
extern "C" sai_status_t mdio_read(uint64_t platform_context, uint32_t mdio_addr, uint32_t reg_addr,
uint32_t number_of_registers, uint32_t *data)
{
int rc = SAI_STATUS_FAILURE;
char cmd[SAI_IPC_BUFF_SIZE], resp[SAI_IPC_BUFF_SIZE];

if (number_of_registers > 1)
{
printf("Multiple register reads are not supported, num_of_registers: %d\n", number_of_registers);
return SAI_STATUS_FAILURE;
}

pthread_mutex_lock(&mutex);

sprintf(cmd, "mdio 0x%x 0x%x\n", mdio_addr, reg_addr);
if (syncd_mdio_ipc_command(cmd, resp) == 0)
{
*data = (uint32_t)strtoul(strchrnul(resp, ' ') + 1, NULL, 0);
rc = SAI_STATUS_SUCCESS;
}

pthread_mutex_unlock(&mutex);
return rc;
}

/* Function to write data to MDIO interface */
extern "C" sai_status_t mdio_write(uint64_t platform_context, uint32_t mdio_addr, uint32_t reg_addr,
uint32_t number_of_registers, const uint32_t *data)
{
int rc = SAI_STATUS_FAILURE;
char cmd[SAI_IPC_BUFF_SIZE], resp[SAI_IPC_BUFF_SIZE];

if (number_of_registers > 1)
{
printf("Multiple register reads are not supported, num_of_registers: %d\n", number_of_registers);
return SAI_STATUS_FAILURE;
}

pthread_mutex_lock(&mutex);

sprintf(cmd, "mdio 0x%x 0x%x 0x%x\n", mdio_addr, reg_addr, *data);
if (syncd_mdio_ipc_command(cmd, resp) == 0)
{
rc = SAI_STATUS_SUCCESS;
}

pthread_mutex_unlock(&mutex);
return rc;
}

/* Function to read data using clause 22 from MDIO interface */
extern "C" sai_status_t mdio_read_cl22(uint64_t platform_context, uint32_t mdio_addr, uint32_t reg_addr,
uint32_t number_of_registers, uint32_t *data)
{
int rc = SAI_STATUS_FAILURE;
char cmd[SAI_IPC_BUFF_SIZE], resp[SAI_IPC_BUFF_SIZE];

if (number_of_registers > 1)
{
printf("Multiple register reads are not supported, num_of_registers: %d\n", number_of_registers);
return SAI_STATUS_FAILURE;
}

pthread_mutex_lock(&mutex);

sprintf(cmd, "mdio-cl22 0x%x 0x%x\n", mdio_addr, reg_addr);
if (syncd_mdio_ipc_command(cmd, resp) == 0)
{
*data = (uint32_t)strtoul(strchrnul(resp, ' ') + 1, NULL, 0);
rc = SAI_STATUS_SUCCESS;
}

pthread_mutex_unlock(&mutex);
return rc;
}

/* Function to write data using clause 22 to MDIO interface */
extern "C" sai_status_t mdio_write_cl22(uint64_t platform_context, uint32_t mdio_addr, uint32_t reg_addr,
uint32_t number_of_registers, const uint32_t *data)
{
int rc = SAI_STATUS_FAILURE;
char cmd[SAI_IPC_BUFF_SIZE], resp[SAI_IPC_BUFF_SIZE];

if (number_of_registers > 1)
{
printf("Multiple register reads are not supported, num_of_registers: %d\n", number_of_registers);
return SAI_STATUS_FAILURE;
}

pthread_mutex_lock(&mutex);

sprintf(cmd, "mdio-cl22 0x%x 0x%x 0x%x\n", mdio_addr, reg_addr, *data);
if (syncd_mdio_ipc_command(cmd, resp) == 0)
{
rc = SAI_STATUS_SUCCESS;
}

pthread_mutex_unlock(&mutex);
return rc;
}
24 changes: 24 additions & 0 deletions platform/components/libmdio-ipc-client/mdio_ipc_client.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef __MDIO_IPC_CLIENT_H__
#define __MDIO_IPC_CLIENT_H__

#include <stdint.h>
#include <unistd.h>

extern "C" {
#include "sai.h"
}

/* Function declarations */
extern "C" {
sai_status_t mdio_read(uint64_t platform_context, uint32_t mdio_addr, uint32_t reg_addr,
uint32_t number_of_registers, uint32_t *data);
sai_status_t mdio_write(uint64_t platform_context, uint32_t mdio_addr,
uint32_t reg_addr, uint32_t number_of_registers, uint32_t *data);

sai_status_t mdio_read_cl22(uint64_t platform_context, uint32_t mdio_addr, uint32_t reg_addr,
uint32_t number_of_registers, uint32_t *data);
sai_status_t mdio_write_cl22(uint64_t platform_context, uint32_t mdio_addr,
uint32_t reg_addr, uint32_t number_of_registers, uint32_t *data);
}

#endif /* __MDIO_IPC_CLIENT_H__ */