1 /*
2  * sff-common.h: Implements SFF-8024 Rev 4.0 i.e. Specifcation
3  * of pluggable I/O configuration
4  *
5  * Common utilities across SFF-8436/8636 and SFF-8472/8079
6  * are defined in this file
7  *
8  * Copyright 2010 Solarflare Communications Inc.
9  * Aurelien Guillaume <aurelien@iwi.me> (C) 2012
10  * Copyright (C) 2014 Cumulus networks Inc.
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Freeoftware Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  *  Vidya Sagar Ravipati <vidya@cumulusnetworks.com>
18  *   This implementation is loosely based on current SFP parser
19  *   and SFF-8024 specs (ftp://ftp.seagate.com/pub/sff/SFF-8024.PDF)
20  *   by SFF Committee.
21  */
22 
23 #ifndef SFF_COMMON_H__
24 #define SFF_COMMON_H__
25 
26 #include <stdio.h>
27 #include "internal.h"
28 
29 #define SFF8024_ID_OFFSET				0x00
30 #define  SFF8024_ID_UNKNOWN				0x00
31 #define  SFF8024_ID_GBIC				0x01
32 #define  SFF8024_ID_SOLDERED_MODULE		0x02
33 #define  SFF8024_ID_SFP					0x03
34 #define  SFF8024_ID_300_PIN_XBI			0x04
35 #define  SFF8024_ID_XENPAK				0x05
36 #define  SFF8024_ID_XFP					0x06
37 #define  SFF8024_ID_XFF					0x07
38 #define  SFF8024_ID_XFP_E				0x08
39 #define  SFF8024_ID_XPAK				0x09
40 #define  SFF8024_ID_X2					0x0A
41 #define  SFF8024_ID_DWDM_SFP			0x0B
42 #define  SFF8024_ID_QSFP				0x0C
43 #define  SFF8024_ID_QSFP_PLUS			0x0D
44 #define  SFF8024_ID_CXP					0x0E
45 #define  SFF8024_ID_HD4X				0x0F
46 #define  SFF8024_ID_HD8X				0x10
47 #define  SFF8024_ID_QSFP28				0x11
48 #define  SFF8024_ID_CXP2				0x12
49 #define  SFF8024_ID_CDFP				0x13
50 #define  SFF8024_ID_HD4X_FANOUT			0x14
51 #define  SFF8024_ID_HD8X_FANOUT			0x15
52 #define  SFF8024_ID_CDFP_S3				0x16
53 #define  SFF8024_ID_MICRO_QSFP			0x17
54 #define  SFF8024_ID_LAST				SFF8024_ID_MICRO_QSFP
55 #define  SFF8024_ID_UNALLOCATED_LAST	0x7F
56 #define  SFF8024_ID_VENDOR_START		0x80
57 #define  SFF8024_ID_VENDOR_LAST			0xFF
58 
59 #define  SFF8024_CTOR_UNKNOWN			0x00
60 #define  SFF8024_CTOR_SC				0x01
61 #define  SFF8024_CTOR_FC_STYLE_1		0x02
62 #define  SFF8024_CTOR_FC_STYLE_2		0x03
63 #define  SFF8024_CTOR_BNC_TNC			0x04
64 #define  SFF8024_CTOR_FC_COAX			0x05
65 #define  SFF8024_CTOR_FIBER_JACK		0x06
66 #define  SFF8024_CTOR_LC				0x07
67 #define  SFF8024_CTOR_MT_RJ				0x08
68 #define  SFF8024_CTOR_MU				0x09
69 #define  SFF8024_CTOR_SG				0x0A
70 #define  SFF8024_CTOR_OPT_PT			0x0B
71 #define  SFF8024_CTOR_MPO				0x0C
72 #define  SFF8024_CTOR_MPO_2				0x0D
73 /* 0E-1Fh --- Reserved */
74 #define  SFF8024_CTOR_HSDC_II			0x20
75 #define  SFF8024_CTOR_COPPER_PT			0x21
76 #define  SFF8024_CTOR_RJ45				0x22
77 #define  SFF8024_CTOR_NO_SEPARABLE		0x23
78 #define  SFF8024_CTOR_MXC_2x16			0x24
79 #define  SFF8024_CTOR_LAST				SFF8024_CTOR_MXC_2x16
80 #define  SFF8024_CTOR_UNALLOCATED_LAST	0x7F
81 #define  SFF8024_CTOR_VENDOR_START		0x80
82 #define  SFF8024_CTOR_VENDOR_LAST		0xFF
83 
84 /* ENCODING Values */
85 #define  SFF8024_ENCODING_UNSPEC		0x00
86 #define  SFF8024_ENCODING_8B10B			0x01
87 #define  SFF8024_ENCODING_4B5B			0x02
88 #define  SFF8024_ENCODING_NRZ			0x03
89 /*
90  * Value: 04h
91  * SFF-8472      - Manchester
92  * SFF-8436/8636 - SONET Scrambled
93  */
94 #define  SFF8024_ENCODING_4h			0x04
95 /*
96  * Value: 05h
97  * SFF-8472      - SONET Scrambled
98  * SFF-8436/8636 - 64B/66B
99  */
100 #define  SFF8024_ENCODING_5h			0x05
101 /*
102  * Value: 06h
103  * SFF-8472      - 64B/66B
104  * SFF-8436/8636 - Manchester
105  */
106 #define  SFF8024_ENCODING_6h			0x06
107 #define  SFF8024_ENCODING_256B			0x07
108 #define  SFF8024_ENCODING_PAM4			0x08
109 
110 /* Most common case: 16-bit unsigned integer in a certain unit */
111 #define OFFSET_TO_U16(offset) \
112 		(id[offset] << 8 | id[(offset) + 1])
113 
114 # define PRINT_xX_PWR(string, var)                             \
115 		printf("\t%-41s : %.4f mW / %.2f dBm\n", (string),         \
116 		      (double)((var) / 10000.),                           \
117 		       convert_mw_to_dbm((double)((var) / 10000.)))
118 
119 #define PRINT_BIAS(string, bias_cur)                             \
120 		printf("\t%-41s : %.3f mA\n", (string),                       \
121 		      (double)(bias_cur / 500.))
122 
123 #define PRINT_TEMP(string, temp)                                   \
124 		printf("\t%-41s : %.2f degrees C / %.2f degrees F\n", \
125 		      (string), (double)(temp / 256.),                \
126 		      (double)(temp / 256. * 1.8 + 32.))
127 
128 #define PRINT_VCC(string, sfp_voltage)          \
129 		printf("\t%-41s : %.4f V\n", (string),       \
130 		      (double)(sfp_voltage / 10000.))
131 
132 # define PRINT_xX_THRESH_PWR(string, var, index)                       \
133 		PRINT_xX_PWR(string, (var)[(index)])
134 
135 /* Channel Monitoring Fields */
136 struct sff_channel_diags {
137 	__u16 bias_cur;      /* Measured bias current in 2uA units */
138 	__u16 rx_power;      /* Measured RX Power */
139 	__u16 tx_power;      /* Measured TX Power */
140 };
141 
142 /* Module Monitoring Fields */
143 struct sff_diags {
144 
145 #define MAX_CHANNEL_NUM 4
146 #define LWARN 0
147 #define HWARN 1
148 #define LALRM 2
149 #define HALRM 3
150 #define MCURR 4
151 
152 	/* Supports DOM */
153 	__u8 supports_dom;
154 	/* Supports alarm/warning thold */
155 	__u8 supports_alarms;
156 	/* RX Power: 0 = OMA, 1 = Average power */
157 	__u8  rx_power_type;
158 	/* TX Power: 0 = Not supported, 1 = Average power */
159 	__u8  tx_power_type;
160 
161 	__u8 calibrated_ext;    /* Is externally calibrated */
162 	/* [5] tables are low/high warn, low/high alarm, current */
163 	/* SFP voltage in 0.1mV units */
164 	__u16 sfp_voltage[5];
165 	/* SFP Temp in 16-bit signed 1/256 Celcius */
166 	__s16 sfp_temp[5];
167 	/* Measured bias current in 2uA units */
168 	__u16 bias_cur[5];
169 	/* Measured TX Power */
170 	__u16 tx_power[5];
171 	/* Measured RX Power */
172 	__u16 rx_power[5];
173 	struct sff_channel_diags scd[MAX_CHANNEL_NUM];
174 };
175 
176 double convert_mw_to_dbm(double mw);
177 void sff_show_value_with_unit(const __u8 *id, unsigned int reg,
178 			      const char *name, unsigned int mult,
179 			      const char *unit);
180 void sff_show_ascii(const __u8 *id, unsigned int first_reg,
181 		    unsigned int last_reg, const char *name);
182 void sff_show_thresholds(struct sff_diags sd);
183 
184 void sff8024_show_oui(const __u8 *id, int id_offset);
185 void sff8024_show_identifier(const __u8 *id, int id_offset);
186 void sff8024_show_connector(const __u8 *id, int ctor_offset);
187 void sff8024_show_encoding(const __u8 *id, int encoding_offset, int sff_type);
188 
189 #endif /* SFF_COMMON_H__ */
190