diff --git a/packages/base/any/oom-shim/src/module/inc/oom-shim/oom-shim.h b/packages/base/any/oom-shim/src/module/inc/oom-shim/oom-shim.h index e69de29b..0925b787 100644 --- a/packages/base/any/oom-shim/src/module/inc/oom-shim/oom-shim.h +++ b/packages/base/any/oom-shim/src/module/inc/oom-shim/oom-shim.h @@ -0,0 +1 @@ +#define MAXPORTS 6 diff --git a/packages/base/any/oom-shim/src/module/inc/oom-shim/oom_south.h b/packages/base/any/oom-shim/src/module/inc/oom-shim/oom_south.h new file mode 100644 index 00000000..fef10e0c --- /dev/null +++ b/packages/base/any/oom-shim/src/module/inc/oom-shim/oom_south.h @@ -0,0 +1,230 @@ +/****************************** +* +* Southbound API definition for +* Open Optical Monitoring (OOM) initiative under the +* umbrella of OCP. +* +* Copyright 2015 Finisar Inc. +* +* LIKELY TO CHANGE, no promises of compatibility with future +* versions is made or implied +* +* Version: 0.4, January 28, 2016 (added oom_get_port(n)) +* Author: Don Bollinger +* +*******************************/ + +#include + +/* Discovery definitions */ + +/* + * list of valid port types + * Values are from SFF-8436 spec (rev 4.8, page 74) + * note OOM_PORT_TYPE_NOT_PRESENT to indicate no + * module is present in this port + */ + +typedef enum oom_port_class_e { + OOM_PORT_CLASS_UNKNOWN = 0x00, + OOM_PORT_CLASS_SFF = 0x01, + OOM_PORT_CLASS_CFP = 0x02, +} oom_port_class_t; + + +/* Define the elements of a port + * Note: seq_num is an implementation defined magic + * number to detect that the module + * on this port has been removed/inserted since this + * port was last accessed + * port_flags is implementation dependent, for use + * by the underlying NOS and switch + * port_flags should NOT be used or modified by the + * decode layer or above + */ +typedef struct oom_port_s { + void *handle; /* opaque handle for this port */ + oom_port_class_t oom_class; /* class is SFF or CFP */ + char name[32]; /* 32 bytes for a human readable name */ +} oom_port_t; + + +/* + * get the list of available ports, as an array + * of oom_port_t structs. 'listsize' indicates the + * number of ports that will fit in the portlist[] array. + * + * If there are listsize or fewer ports, and the portlist[] + * array is new or out of date, then the shim populates + * the portlist structure, and returns 0 (success). + * + * If the portlist structure is already current, then the + * shim does not modify portlist[], and returns 1 (no change). + * This is intended as a way to poll for changes to the ports + * (eg modules added, deleted, replaced, etc) + * + * If there are more than listize ports, the shim + * returns -ENOMEM, to indicate that a larger portlist[] + * array is required. + * + * If called as oom_get_portlist(NULL, 0), then the shim will + * return the number of ports, ie the minimum value of listsize. Note + * that some implementations can dynamically add ports, so the return + * value is a very good hint, but not a guarantee as to the required + * size of the portlist[] structure. + */ +int oom_get_portlist(oom_port_t portlist[], int listsize); + + +/* Read/write control "PINS" function definitions */ + +/* note that these 'control pins' functions are in limbo right + * now, and may not be implemented until later, if at all. + * Developers of "southbound shims" may choose to delay + * implementation of oom_{get, set}_function() + */ + +/* list of functions that can be controlled */ +typedef enum oom_functions_e { + OOM_FUNCTIONS_TX_FAULT, + OOM_FUNCTIONS_TX_DISABLE, + OOM_FUNCTIONS_MODULE_ABSENT, + OOM_FUNCTIONS_RS0, + OOM_FUNCTIONS_RS1, + /* more control functions to be defined here */ + OOM_FUNCTIONS_RXLOSS_OF_SIG, + OOM_FUNCTIONS_LAST = OOM_FUNCTIONS_RXLOSS_OF_SIG, + OOM_FUNCTIONS_COUNT, + OOM_FUNCTIONS_INVALID = -1, +} oom_functions_t; + +/* + * read a function + * rv will be 1 for asserted or enabled, 0 if not + * returns 0 on success, or negative error code + */ +int oom_get_function(oom_port_t* port, oom_functions_t function, int* rv); + +/* + * write a function + * value should be 1 for asserted or enabled, 0 if not + * returns 0 on success, or negative error code + */ +int oom_set_function(oom_port_t* port, oom_functions_t function, int value); + + +/* Read/write EEPROM definitions */ + +/* + * read EEPROM + * address: the 2-wire (i2c) address, per the SFF specs, + * eg A0h, A2h, A8h, etc. (160, 162, 168 respectively.) + * Note that this address points to 256 bytes of data. + * Bytes 0-127 are intrinsic to this address space. + * Bytes 128-255 are the contents of the "page" selected + * in byte 127. (The page select byte will be written by + * the driver as part of this call. DO NOT explicitly + * set byte 127 to select a page.) + * Thus there are 256 pages (based on one + * byte of page select in byte 127). ONE of these pages + * can be accessed in an EEPROM read, and the content + * of that page will be at offset 128-255 of the address + * space. Page contents starts at offset=128. It is NOT + * necessary to read the first 128 bytes of the address + * space to access the page contents in the second 128 + * bytes. See the specs for a further description of + * this access architecture, and the content of each page. + * Note: Bytes 0-127 do not depend on the value of page. + * Reading 256 bytes, starting at offset 0, will read both + * the lower half of the address space, AND the page selected. + * page: page of EEPROM to read from + * offset: byte location within the address space to begin + * transferring data from. Remember, offset 0-127 reference + * the first 128 bytes of "address" range. Their contents + * do not depend on the value of page. Page content begins + * at offset=128. + * len: the number of bytes to be read + * note that (offset + len) must be no more than 256, as + * there are only 256 bytes of data available at A0, A2, etc + * data: receives the memory contents + * returns: the number of bytes read, or a + * negative error code + */ +int oom_get_memory_sff(oom_port_t* port, int address, int page, int offset, int len, uint8_t* data); + + +/* + * write EEPROM + * address: the 2-wire (i2c) address, per the SFF specs, + * eg A0h, A2h, A8h, etc. (160, 162, 168 respectively.) + * Note that this address points to 256 bytes of data. + * Bytes 0-127 are intrinsic to this address space. + * Bytes 128-255 are the contents of the "page" selected + * in byte 127. (The page select byte will be written by + * the driver as part of this call. DO NOT explicitly + * set byte 127 to select a page.) + * Thus there are 256 pages (based on one + * byte of page select in byte 127). ONE of these pages + * can be accessed in an EEPROM write, and data written + * to that page must be written to offset 128-255 of the + * address space. + * Page contents starts at offset=128. It is NOT + * necessary to write the first 128 bytes of the address + * space to access the page contents in the second 128 + * bytes. See the specs for a further description of + * this access architecture, and the content of each page. + * Note: Writes to bytes 0-127 will go to the lower half + * of the address space, and do not depend on the + * value of page. Writing 256 bytes, starting at offset 0, + * will write both the lower half of the address space AND + * the page selected. + * page: page of EEPROM to write to + * offset: byte location within the address space to begin + * transferring data from. Remember, offset 0-127 reference + * the first 128 bytes of "address" range. Their contents + * do not depend on the value of page. Page content begins + * at offset=128. + * len: the number of bytes to be written + * note that (offset + len) must be no more than 256, as + * there are only 256 bytes of address space at A0, A2, etc + * data: data to be written to memory + * returns: the number of bytes written, or a + * negative error code + */ +int oom_set_memory_sff(oom_port_t* port, int address, int page, int offset, int len, uint8_t* data); + +/* + * read 16 bit oriented EEPROM + * CFP modules (for example) do not use 2-wire (i2c) addresses + * nor do they use the page table scheme of SFP, XFP, QSFP, etc + * their EEPROM is addressed in 16 bit words, in a 32K word + * linear address space from 8000hex to FFFFhex + * (0000-7FFF are reserved for IEEE 802.3 use) + * the interface below is for these types of modules + * port: an OOM port structure + * address: address between 0x8000 and 0xFFFF to begin read + * Each consecutive address is a 16 bit "register" + * (not an 8 bit byte) + * len: number of 16 bit "registers" to read + * data: receives the memory contents + * returns the number of words read, or a negative error code + */ +int oom_get_memory_cfp(oom_port_t* port, int address, int len, uint16_t* data); + +/* + * write 16 bit oriented EEPROM + * CFP modules (for example) do not use 2-wire (i2c) addresses + * nor do they use the page table scheme of SFP, XFP, QSFP, etc + * their EEPROM is addressed in 16 bit words, in a 32K word + * linear address space from 8000hex to FFFFhex + * (0000-7FFF are reserved for IEEE 802.3 use) + * the interface below is for these types of modules + * port: an OOM port structure + * address: address between 0x8000 and 0xFFFF to begin write + * Each consecutive address is a 16 bit "register" + * (not an 8 bit byte) + * len: number of 16 bit "registers" to write + * data: data to be written to memory + * returns the number of words written, or a negative error code + */ +int oom_set_memory_cfp(oom_port_t* port, int address, int len, uint16_t* data); diff --git a/packages/base/any/oom-shim/src/module/src/Makefile b/packages/base/any/oom-shim/src/module/src/Makefile index 87a73132..1259eda6 100644 --- a/packages/base/any/oom-shim/src/module/src/Makefile +++ b/packages/base/any/oom-shim/src/module/src/Makefile @@ -26,5 +26,5 @@ include ../../../../init.mk ucli: - $(SUBMODULE_BIGCODE)/tools/uclihandlers.py onlpie_ucli.c + $(SUBMODULE_BIGCODE)/tools/uclihandlers.py oom_shim_ucli.c diff --git a/packages/base/any/oom-shim/src/module/src/oom_shim.c b/packages/base/any/oom-shim/src/module/src/oom_shim.c index 5e866c30..535a8a85 100644 --- a/packages/base/any/oom-shim/src/module/src/oom_shim.c +++ b/packages/base/any/oom-shim/src/module/src/oom_shim.c @@ -1,7 +1,102 @@ +/************************************************************ + * + * + * Copyright 2016 Big Switch 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. + * + * + ************************************************************ + * + * + * + ***********************************************************/ #include +#include +#include +#include +#include +#include +#include +#include -int test_func(int argc) -{ +int Initialized = 0; - printf("Looks like it works...\n"); +/*Initializing the SFP and ONLP modules*/ +void __oom_shim_module_init__(void) { + onlp_init(); + Initialized = 1; +} + +/*Gets the portlist of the SFP ports on the switch*/ +int oom_get_portlist(oom_port_t portlist[], int listsize){ + + int port,i=0; + oom_port_t* pptr; + + if(Initialized == 0){ + __oom_shim_module_init__(); + } + + onlp_sfp_bitmap_t bitmap; + onlp_sfp_bitmap_t_init(&bitmap); + onlp_sfp_bitmap_get(&bitmap); + + if ((portlist == NULL) && (listsize == 0)){ /* asking # of ports */ + if(AIM_BITMAP_COUNT(&bitmap) == 0){ + printf("No SFPs on this platform.\n"); + return 0; + } + else + return AIM_BITMAP_COUNT(&bitmap); + } + + AIM_BITMAP_ITER(&bitmap, port){ + int rv; + uint8_t* data; + + pptr = &portlist[i]; + pptr->handle = (void *)(uintptr_t)port; + pptr->oom_class = OOM_PORT_CLASS_SFF; + sprintf(pptr->name, "port%d", port); + i++; + + rv = onlp_sfp_is_present(port); + if(rv == 0){ + printf("module %d is not present\n", port); + continue; + } + + if(rv < 0){ + printf("%4d Error\n", port); + continue; + } + + rv = onlp_sfp_eeprom_read(port, &data); + + if(rv < 0){ + printf("%4d Error}\n", port); + continue; + } + + sff_info_t sff; + sff_info_init(&sff, data); + if(!sff.supported) { + printf("%13d UNK\n", port); + continue; + } + printf("The sfp_type is : %-14s",sff.sfp_type_name); + } + return 0; }