freebsd-dev/lib/libifconfig/libifconfig_sfp_tables.tpl.c
Ryan Moeller 94cba8034b Move ifconfig SFP status functionality into libifconfig
libifconfig_sfp.h provides an API in libifconfig for querying SFP module
properties, operational status, and vendor strings, as well as descriptions
of the various fields, string conversions, and other useful helpers for
implementing user interfaces.

SFP module status is obtained by reading registers via an I2C interface.
Descriptions of these registers and the values therein have been collected
in a Lua table which is used to generate all the boilerplace C headers and
source files for accessing these values, their names, and descriptions.
The generated code is fully commented and readable.

This is the first use of libifconfig in ifconfig itself.  For now, the
scope remains very limited.  Over time, more of ifconfig will be replaced
with libifconfig.

Some minor changes to the formatting of ifconfig output have been made:
- Module memory hex dumps are indented one extra space as a result of using
hexdump(3) instead of a bespoke hex dump function.
- Media descriptions have an added two-character short-name in parenthesis.
- QSFP modules were incorrectly displaying TX bias current as power.  Now
  TX channels display bias current, and this change has been made for both
  SFP and QSFP modules for consistency.

A Lua binding for libifconfig including this functionality is implemented
but has not been included in this commit.  The plan is for it to be
committed after dynamic module loading has been enabled in flua.

Reviewed by:	kp, melifaro
Relnotes:	yes
Differential Revision:	https://reviews.freebsd.org/D25494
2020-08-09 16:27:28 +00:00

125 lines
3.2 KiB
C

/*-
* Copyright (c) 2020, Ryan Moeller <freqlabs@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
{# THIS IS A TEMPLATE PROCESSED BY lib/libifconfig/sfp.lua #}
#include <libifconfig_sfp_tables.h>
#include <libifconfig_sfp_tables_internal.h>
struct sfp_enum_metadata {
int value; /* numeric discriminant value */
const char *symbol; /* symbolic name */
const char *description; /* brief description */
const char *display; /* shortened display name */
};
const struct sfp_enum_metadata *
find_metadata(const struct sfp_enum_metadata *table, int value)
{
while (table->value != value && table->symbol != NULL)
++table;
return (table->symbol != NULL ? table : NULL);
}
{%
for _, ent in ipairs(enums) do
if type(ent) == "string" then
%}
/*
* {*ent*}
*/
{%
else
local enum = ent
local name = "sfp_"..enum.name
local sym, desc, disp
%}
static const struct sfp_enum_metadata {*name*}_table_[] = {
{%
for _, item in ipairs(enum.values) do
_, sym, desc, disp = table.unpack(item)
local symbol = string.upper(name).."_"..sym
%}
{
.value = {*symbol*},
.symbol = "{*symbol*}",
.description = "{*desc*}",
{%
if disp then
%}
.display = "{*disp*}",
{%
end
%}
},
{%
end
%}
{0}
};
const struct sfp_enum_metadata *{*name*}_table = {*name*}_table_;
const char *
ifconfig_{*name*}_symbol(enum {*name*} v)
{
const struct sfp_enum_metadata *metadata;
if ((metadata = find_metadata({*name*}_table, v)) == NULL)
return (NULL);
return (metadata->symbol);
}
const char *
ifconfig_{*name*}_description(enum {*name*} v)
{
const struct sfp_enum_metadata *metadata;
if ((metadata = find_metadata({*name*}_table, v)) == NULL)
return (NULL);
return (metadata->description);
}
{%
if disp then
%}
const char *
ifconfig_{*name*}_display(enum {*name*} v)
{
const struct sfp_enum_metadata *metadata;
if ((metadata = find_metadata({*name*}_table, v)) == NULL)
return (NULL);
return (metadata->display);
}
{%
end
end
end
%}