summaryrefslogtreecommitdiffstats
path: root/sff-common.h
blob: 899dc5be15b107a21b21d9956e3a1e248eda8e87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/*
 * sff-common.h: Implements SFF-8024 Rev 4.0 i.e. Specifcation
 * of pluggable I/O configuration
 *
 * Common utilities across SFF-8436/8636 and SFF-8472/8079
 * are defined in this file
 *
 * Copyright 2010 Solarflare Communications Inc.
 * Aurelien Guillaume <aurelien@iwi.me> (C) 2012
 * Copyright (C) 2014 Cumulus networks Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Freeoftware Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 *  Vidya Sagar Ravipati <vidya@cumulusnetworks.com>
 *   This implementation is loosely based on current SFP parser
 *   and SFF-8024 specs (ftp://ftp.seagate.com/pub/sff/SFF-8024.PDF)
 *   by SFF Committee.
 */

#ifndef SFF_COMMON_H__
#define SFF_COMMON_H__

#include <stdio.h>
#include "internal.h"

/* Revision compliance */
#define  SFF8636_REV_UNSPECIFIED		0x00
#define  SFF8636_REV_8436_48			0x01
#define  SFF8636_REV_8436_8636			0x02
#define  SFF8636_REV_8636_13			0x03
#define  SFF8636_REV_8636_14			0x04
#define  SFF8636_REV_8636_15			0x05
#define  SFF8636_REV_8636_20			0x06
#define  SFF8636_REV_8636_27			0x07

#define  SFF8024_ID_OFFSET				0x00
#define  SFF8024_ID_UNKNOWN				0x00
#define  SFF8024_ID_GBIC				0x01
#define  SFF8024_ID_SOLDERED_MODULE		0x02
#define  SFF8024_ID_SFP					0x03
#define  SFF8024_ID_300_PIN_XBI			0x04
#define  SFF8024_ID_XENPAK				0x05
#define  SFF8024_ID_XFP					0x06
#define  SFF8024_ID_XFF					0x07
#define  SFF8024_ID_XFP_E				0x08
#define  SFF8024_ID_XPAK				0x09
#define  SFF8024_ID_X2					0x0A
#define  SFF8024_ID_DWDM_SFP			0x0B
#define  SFF8024_ID_QSFP				0x0C
#define  SFF8024_ID_QSFP_PLUS			0x0D
#define  SFF8024_ID_CXP					0x0E
#define  SFF8024_ID_HD4X				0x0F
#define  SFF8024_ID_HD8X				0x10
#define  SFF8024_ID_QSFP28				0x11
#define  SFF8024_ID_CXP2				0x12
#define  SFF8024_ID_CDFP				0x13
#define  SFF8024_ID_HD4X_FANOUT			0x14
#define  SFF8024_ID_HD8X_FANOUT			0x15
#define  SFF8024_ID_CDFP_S3				0x16
#define  SFF8024_ID_MICRO_QSFP			0x17
#define  SFF8024_ID_QSFP_DD				0x18
#define  SFF8024_ID_OSFP				0x19
#define  SFF8024_ID_DSFP				0x1B
#define  SFF8024_ID_QSFP_PLUS_CMIS			0x1E
#define  SFF8024_ID_SFP_DD_CMIS				0x1F
#define  SFF8024_ID_SFP_PLUS_CMIS			0x20
#define  SFF8024_ID_LAST				SFF8024_ID_SFP_PLUS_CMIS
#define  SFF8024_ID_UNALLOCATED_LAST	0x7F
#define  SFF8024_ID_VENDOR_START		0x80
#define  SFF8024_ID_VENDOR_LAST			0xFF

#define  SFF8024_CTOR_UNKNOWN			0x00
#define  SFF8024_CTOR_SC				0x01
#define  SFF8024_CTOR_FC_STYLE_1		0x02
#define  SFF8024_CTOR_FC_STYLE_2		0x03
#define  SFF8024_CTOR_BNC_TNC			0x04
#define  SFF8024_CTOR_FC_COAX			0x05
#define  SFF8024_CTOR_FIBER_JACK		0x06
#define  SFF8024_CTOR_LC				0x07
#define  SFF8024_CTOR_MT_RJ				0x08
#define  SFF8024_CTOR_MU				0x09
#define  SFF8024_CTOR_SG				0x0A
#define  SFF8024_CTOR_OPT_PT			0x0B
#define  SFF8024_CTOR_MPO				0x0C
#define  SFF8024_CTOR_MPO_2				0x0D
/* 0E-1Fh --- Reserved */
#define  SFF8024_CTOR_HSDC_II			0x20
#define  SFF8024_CTOR_COPPER_PT			0x21
#define  SFF8024_CTOR_RJ45				0x22
#define  SFF8024_CTOR_NO_SEPARABLE		0x23
#define  SFF8024_CTOR_MXC_2x16			0x24
#define  SFF8024_CTOR_CS_OPTICAL		0x25
#define  SFF8024_CTOR_CS_OPTICAL_MINI		0x26
#define  SFF8024_CTOR_MPO_2X12			0x27
#define  SFF8024_CTOR_MPO_1X16			0x28
#define  SFF8024_CTOR_LAST			SFF8024_CTOR_MPO_1X16

#define  SFF8024_CTOR_NO_SEP_QSFP_DD		0x6F
#define  SFF8024_CTOR_UNALLOCATED_LAST		0x7F
#define  SFF8024_CTOR_VENDOR_START		0x80
#define  SFF8024_CTOR_VENDOR_LAST		0xFF

/* ENCODING Values */
#define  SFF8024_ENCODING_UNSPEC		0x00
#define  SFF8024_ENCODING_8B10B			0x01
#define  SFF8024_ENCODING_4B5B			0x02
#define  SFF8024_ENCODING_NRZ			0x03
/*
 * Value: 04h
 * SFF-8472      - Manchester
 * SFF-8436/8636 - SONET Scrambled
 */
#define  SFF8024_ENCODING_4h			0x04
/*
 * Value: 05h
 * SFF-8472      - SONET Scrambled
 * SFF-8436/8636 - 64B/66B
 */
#define  SFF8024_ENCODING_5h			0x05
/*
 * Value: 06h
 * SFF-8472      - 64B/66B
 * SFF-8436/8636 - Manchester
 */
#define  SFF8024_ENCODING_6h			0x06
#define  SFF8024_ENCODING_256B			0x07
#define  SFF8024_ENCODING_PAM4			0x08

/* Most common case: 16-bit unsigned integer in a certain unit */
#define OFFSET_TO_U16_PTR(ptr, offset) (ptr[offset] << 8 | ptr[(offset) + 1])
#define OFFSET_TO_U16(offset) OFFSET_TO_U16_PTR(id, offset)

# define PRINT_xX_PWR(string, var)                             \
		printf("\t%-41s : %.4f mW / %.2f dBm\n", (string),         \
		      (double)((var) / 10000.),                           \
		       convert_mw_to_dbm((double)((var) / 10000.)))

#define PRINT_BIAS(string, bias_cur)                             \
		printf("\t%-41s : %.3f mA\n", (string),                       \
		      (double)(bias_cur / 500.))

#define PRINT_TEMP(string, temp)                                   \
		printf("\t%-41s : %.2f degrees C / %.2f degrees F\n", \
		      (string), (double)(temp / 256.),                \
		      (double)(temp / 256. * 1.8 + 32.))

#define PRINT_VCC(string, sfp_voltage)          \
		printf("\t%-41s : %.4f V\n", (string),       \
		      (double)(sfp_voltage / 10000.))

# define PRINT_xX_THRESH_PWR(string, var, index)                       \
		PRINT_xX_PWR(string, (var)[(index)])

/* Channel Monitoring Fields */
struct sff_channel_diags {
	__u16 bias_cur;      /* Measured bias current in 2uA units */
	__u16 rx_power;      /* Measured RX Power */
	__u16 tx_power;      /* Measured TX Power */
};

/* Module Monitoring Fields */
struct sff_diags {

#define MAX_CHANNEL_NUM 32
#define LWARN 0
#define HWARN 1
#define LALRM 2
#define HALRM 3
#define MCURR 4

	/* Supports DOM */
	__u8 supports_dom;
	/* Supports alarm/warning thold */
	__u8 supports_alarms;
	/* RX Power: 0 = OMA, 1 = Average power */
	__u8  rx_power_type;
	/* TX Power: 0 = Not supported, 1 = Average power */
	__u8  tx_power_type;

	__u8 calibrated_ext;    /* Is externally calibrated */
	/* [5] tables are low/high warn, low/high alarm, current */
	/* SFP voltage in 0.1mV units */
	__u16 sfp_voltage[5];
	/* SFP Temp in 16-bit signed 1/256 Celcius */
	__s16 sfp_temp[5];
	/* Measured bias current in 2uA units */
	__u16 bias_cur[5];
	/* Measured TX Power */
	__u16 tx_power[5];
	/* Measured RX Power */
	__u16 rx_power[5];
	struct sff_channel_diags scd[MAX_CHANNEL_NUM];
};

double convert_mw_to_dbm(double mw);
void sff_show_value_with_unit(const __u8 *id, unsigned int reg,
			      const char *name, unsigned int mult,
			      const char *unit);
void sff_show_ascii(const __u8 *id, unsigned int first_reg,
		    unsigned int last_reg, const char *name);
void sff_show_lane_status(const char *name, unsigned int lane_cnt,
			  const char *yes, const char *no, unsigned int value);
void sff_show_thresholds(struct sff_diags sd);

void sff8024_show_oui(const __u8 *id, int id_offset);
void sff8024_show_identifier(const __u8 *id, int id_offset);
void sff8024_show_connector(const __u8 *id, int ctor_offset);
void sff8024_show_encoding(const __u8 *id, int encoding_offset, int sff_type);
void sff_show_revision_compliance(const __u8 *id, int rev_offset);

#endif /* SFF_COMMON_H__ */