├── .gitignore ├── doc ├── sff │ ├── INF-8074.PDF │ ├── SFF-8431.PDF │ └── SFF-8472.PDF └── datasheets │ └── PCA9544A.pdf ├── makefile ├── LICENSE ├── README.md └── main.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | main 3 | *.swp 4 | dump 5 | -------------------------------------------------------------------------------- /doc/sff/INF-8074.PDF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feuerrot/sfp-i2c/HEAD/doc/sff/INF-8074.PDF -------------------------------------------------------------------------------- /doc/sff/SFF-8431.PDF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feuerrot/sfp-i2c/HEAD/doc/sff/SFF-8431.PDF -------------------------------------------------------------------------------- /doc/sff/SFF-8472.PDF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feuerrot/sfp-i2c/HEAD/doc/sff/SFF-8472.PDF -------------------------------------------------------------------------------- /doc/datasheets/PCA9544A.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/feuerrot/sfp-i2c/HEAD/doc/datasheets/PCA9544A.pdf -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | all: main 2 | 3 | main: main.o 4 | gcc -o main main.o 5 | 6 | main.o: main.c 7 | gcc -c -Wall -Wextra -Werror --std c99 -O3 main.c 8 | 9 | clean: 10 | rm main 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | SOLIPSISTIC PUBLIC LICENSE 2 | Version 1, April 2013 3 | 4 | Copyright (C) 2013 5 | 6 | Everyone is permitted to copy and distribute verbatim copies of 7 | this license document. Modified copies of this document are 8 | permitted provided that they denounce BOTH the original AND their 9 | copy as mere sense data with no verifiable cause outside the mind. 10 | 11 | SOLIPSISTIC PUBLIC LICENSE 12 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 13 | 14 | 0. The term 'work' refers to the false sense-data distributed 15 | with this license. 16 | 1. The term 'you' refers to the only being who verifiably exists. 17 | 2. The term 'author' refers to the set of delusions whereby you 18 | incorrectly assign external agency to the work. 19 | 3. You may copy, modify and distribute the work without restrictions 20 | provided that you do not believe the author exists, and provided 21 | that you affirm publicly when referring to the work, or when 22 | questioned or interrogated by beings who putatively exist, that 23 | the work does not exist. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sfp-i2c [en] 2 | ## what? 3 | SFP transceiver use I2C to provide information about its manufacturer, the 4 | supported capabilities and more. 5 | Most modules also provide a diagnostic monitoring interface known as DOM, 6 | which can also be read. 7 | 8 | ## how to interface? 9 | There are different alternatives to interface a transceiver. I'm using a 10 | TwinGig Converter Module from Cisco, which allows to interface two SFP 11 | modules by the use of a PCA9544A. 12 | 13 | ## specification 14 | look into doc/ 15 | 16 | # sfp-i2c [de] 17 | ## wat? 18 | SFP(+)-Module (und noch einige andere) haben eine I2C-Schnittstelle, um 19 | diverse Werte auslesen zu können. Standardmäßig vorhanden sind 20 | Informationen wie Hersteller, Teilenummer, Seriennummer und andere, zudem 21 | können auch Diagnoseinformationen vorhanden sein. 22 | 23 | ## Interface? 24 | Da gibt es verschiedene Möglichkeiten. Einerseits kann man natürlich direkt 25 | am SFP-Modul löten, dann gestaltet es sich aber mit der Weiterverwendung 26 | etwas schwierig. Ich verwende ein TwinGig Converter Module von Cisco, da 27 | erhält man direkt zwei SFP-Slots, zwischen denen man ebenfalls via I2C 28 | umschalten kann. Daher wird da wohl noch etwas Code dazu drin landen. 29 | 30 | ## Mehr Informationen? 31 | Benutze die SFF-Spezifikationen im doc-Verzeichnis 32 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | int fh_i2c; 14 | char i2c_bus[] = "/dev/i2c-2"; 15 | 16 | int sfp_info = 0x50; 17 | int sfp_diag = 0x51; 18 | 19 | uint8_t data_info[256]; 20 | uint8_t data_diag[256]; 21 | 22 | void _log(int level, char *log){ 23 | printf("["); 24 | 25 | switch (level){ 26 | case 0: 27 | printf("∀"); 28 | break; 29 | case 1: 30 | printf("+"); 31 | break; 32 | case 2: 33 | printf("!"); 34 | break; 35 | case 3: 36 | printf("?"); 37 | break; 38 | } 39 | 40 | printf("] "); 41 | printf(log); 42 | printf("\n"); 43 | } 44 | 45 | float conv(uint8_t *data, uint16_t div, uint8_t sig){ 46 | 47 | if (sig){ 48 | return ((int16_t) ((data[0] << 8) + data[1]))/(float) div; 49 | } else { 50 | return ((uint16_t) ((data[0] << 8) + data[1]))/(float) div; 51 | } 52 | } 53 | 54 | void open_i2c(void){ 55 | fh_i2c = open(i2c_bus, O_RDWR); 56 | if (fh_i2c < 0){ 57 | _log(2, "fh_i2c < 0"); 58 | printf("Errno: %i", errno); 59 | exit(1); 60 | } 61 | } 62 | 63 | void close_i2c(void){ 64 | close(fh_i2c); 65 | } 66 | 67 | void set_i2c_slave(int slave){ 68 | if (ioctl(fh_i2c, I2C_SLAVE, slave) < 0){ 69 | _log(2, "ioctl < 0"); 70 | exit(1); 71 | } 72 | } 73 | 74 | void dump_i2c_slave(uint8_t *data){ 75 | char buf[1] = {0x00}; 76 | 77 | write(fh_i2c, buf, 1); 78 | 79 | for (int i=0; i <= 255; i++){ 80 | read(fh_i2c, buf, 1); 81 | data[i] = buf[0]; 82 | } 83 | } 84 | 85 | void print_data(uint8_t *data){ 86 | for (int i=0; i <= 255; i += 16){ 87 | printf("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", 88 | data[i], data[i+1], data[i+2], data[i+3], data[i+4], 89 | data[i+5], data[i+6], data[i+7], data[i+8], data[i+9], 90 | data[i+10], data[i+11], data[i+12], data[i+13], data[i+14], 91 | data[i+15]); 92 | } 93 | } 94 | 95 | void print_part(uint8_t *data, char *ptype, char *prefix, int start, int len){ 96 | printf("%s: ", prefix); 97 | for (int i=start; i