xref: /aosp_15_r20/external/ethtool/cmis.c (revision 1b481fc3bb1b45d4cf28d1ec12969dc1055f555d)
1*1b481fc3SMaciej Żenczykowski /**
2*1b481fc3SMaciej Żenczykowski  * Description:
3*1b481fc3SMaciej Żenczykowski  *
4*1b481fc3SMaciej Żenczykowski  * This module adds CMIS support to ethtool. The changes are similar to
5*1b481fc3SMaciej Żenczykowski  * the ones already existing in qsfp.c, but customized to use the memory
6*1b481fc3SMaciej Żenczykowski  * addresses and logic as defined in the specification's document.
7*1b481fc3SMaciej Żenczykowski  *
8*1b481fc3SMaciej Żenczykowski  */
9*1b481fc3SMaciej Żenczykowski 
10*1b481fc3SMaciej Żenczykowski #include <stdio.h>
11*1b481fc3SMaciej Żenczykowski #include <math.h>
12*1b481fc3SMaciej Żenczykowski #include <errno.h>
13*1b481fc3SMaciej Żenczykowski #include "internal.h"
14*1b481fc3SMaciej Żenczykowski #include "sff-common.h"
15*1b481fc3SMaciej Żenczykowski #include "cmis.h"
16*1b481fc3SMaciej Żenczykowski #include "netlink/extapi.h"
17*1b481fc3SMaciej Żenczykowski 
18*1b481fc3SMaciej Żenczykowski /* The maximum number of supported Banks. Relevant documents:
19*1b481fc3SMaciej Żenczykowski  * [1] CMIS Rev. 5, page. 128, section 8.4.4, Table 8-40
20*1b481fc3SMaciej Żenczykowski  */
21*1b481fc3SMaciej Żenczykowski #define CMIS_MAX_BANKS	4
22*1b481fc3SMaciej Żenczykowski #define CMIS_CHANNELS_PER_BANK	8
23*1b481fc3SMaciej Żenczykowski #define CMIS_MAX_CHANNEL_NUM	(CMIS_MAX_BANKS * CMIS_CHANNELS_PER_BANK)
24*1b481fc3SMaciej Żenczykowski 
25*1b481fc3SMaciej Żenczykowski /* We are not parsing further than Page 11h. */
26*1b481fc3SMaciej Żenczykowski #define CMIS_MAX_PAGES	18
27*1b481fc3SMaciej Żenczykowski 
28*1b481fc3SMaciej Żenczykowski struct cmis_memory_map {
29*1b481fc3SMaciej Żenczykowski 	const __u8 *lower_memory;
30*1b481fc3SMaciej Żenczykowski 	const __u8 *upper_memory[CMIS_MAX_BANKS][CMIS_MAX_PAGES];
31*1b481fc3SMaciej Żenczykowski #define page_00h upper_memory[0x0][0x0]
32*1b481fc3SMaciej Żenczykowski #define page_01h upper_memory[0x0][0x1]
33*1b481fc3SMaciej Żenczykowski #define page_02h upper_memory[0x0][0x2]
34*1b481fc3SMaciej Żenczykowski };
35*1b481fc3SMaciej Żenczykowski 
36*1b481fc3SMaciej Żenczykowski #define CMIS_PAGE_SIZE		0x80
37*1b481fc3SMaciej Żenczykowski #define CMIS_I2C_ADDRESS	0x50
38*1b481fc3SMaciej Żenczykowski 
39*1b481fc3SMaciej Żenczykowski static struct {
40*1b481fc3SMaciej Żenczykowski 	const char *str;
41*1b481fc3SMaciej Żenczykowski 	int offset;
42*1b481fc3SMaciej Żenczykowski 	__u8 value;	/* Alarm is on if (offset & value) != 0. */
43*1b481fc3SMaciej Żenczykowski } cmis_aw_mod_flags[] = {
44*1b481fc3SMaciej Żenczykowski 	{ "Module temperature high alarm",
45*1b481fc3SMaciej Żenczykowski 	  CMIS_TEMP_AW_OFFSET, CMIS_TEMP_HALARM_STATUS },
46*1b481fc3SMaciej Żenczykowski 	{ "Module temperature low alarm",
47*1b481fc3SMaciej Żenczykowski 	  CMIS_TEMP_AW_OFFSET, CMIS_TEMP_LALARM_STATUS },
48*1b481fc3SMaciej Żenczykowski 	{ "Module temperature high warning",
49*1b481fc3SMaciej Żenczykowski 	  CMIS_TEMP_AW_OFFSET, CMIS_TEMP_HWARN_STATUS },
50*1b481fc3SMaciej Żenczykowski 	{ "Module temperature low warning",
51*1b481fc3SMaciej Żenczykowski 	  CMIS_TEMP_AW_OFFSET, CMIS_TEMP_LWARN_STATUS },
52*1b481fc3SMaciej Żenczykowski 
53*1b481fc3SMaciej Żenczykowski 	{ "Module voltage high alarm",
54*1b481fc3SMaciej Żenczykowski 	  CMIS_VCC_AW_OFFSET, CMIS_VCC_HALARM_STATUS },
55*1b481fc3SMaciej Żenczykowski 	{ "Module voltage low alarm",
56*1b481fc3SMaciej Żenczykowski 	  CMIS_VCC_AW_OFFSET, CMIS_VCC_LALARM_STATUS },
57*1b481fc3SMaciej Żenczykowski 	{ "Module voltage high warning",
58*1b481fc3SMaciej Żenczykowski 	  CMIS_VCC_AW_OFFSET, CMIS_VCC_HWARN_STATUS },
59*1b481fc3SMaciej Żenczykowski 	{ "Module voltage low warning",
60*1b481fc3SMaciej Żenczykowski 	  CMIS_VCC_AW_OFFSET, CMIS_VCC_LWARN_STATUS },
61*1b481fc3SMaciej Żenczykowski 
62*1b481fc3SMaciej Żenczykowski 	{ NULL, 0, 0 },
63*1b481fc3SMaciej Żenczykowski };
64*1b481fc3SMaciej Żenczykowski 
65*1b481fc3SMaciej Żenczykowski static struct {
66*1b481fc3SMaciej Żenczykowski 	const char *fmt_str;
67*1b481fc3SMaciej Żenczykowski 	int offset;
68*1b481fc3SMaciej Żenczykowski 	int adver_offset;	/* In Page 01h. */
69*1b481fc3SMaciej Żenczykowski 	__u8 adver_value;	/* Supported if (offset & value) != 0. */
70*1b481fc3SMaciej Żenczykowski } cmis_aw_chan_flags[] = {
71*1b481fc3SMaciej Żenczykowski 	{ "Laser bias current high alarm   (Chan %d)",
72*1b481fc3SMaciej Żenczykowski 	  CMIS_TX_BIAS_AW_HALARM_OFFSET,
73*1b481fc3SMaciej Żenczykowski 	  CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_BIAS_MON_MASK },
74*1b481fc3SMaciej Żenczykowski 	{ "Laser bias current low alarm    (Chan %d)",
75*1b481fc3SMaciej Żenczykowski 	  CMIS_TX_BIAS_AW_LALARM_OFFSET,
76*1b481fc3SMaciej Żenczykowski 	  CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_BIAS_MON_MASK },
77*1b481fc3SMaciej Żenczykowski 	{ "Laser bias current high warning (Chan %d)",
78*1b481fc3SMaciej Żenczykowski 	  CMIS_TX_BIAS_AW_HWARN_OFFSET,
79*1b481fc3SMaciej Żenczykowski 	  CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_BIAS_MON_MASK },
80*1b481fc3SMaciej Żenczykowski 	{ "Laser bias current low warning  (Chan %d)",
81*1b481fc3SMaciej Żenczykowski 	  CMIS_TX_BIAS_AW_LWARN_OFFSET,
82*1b481fc3SMaciej Żenczykowski 	  CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_BIAS_MON_MASK },
83*1b481fc3SMaciej Żenczykowski 
84*1b481fc3SMaciej Żenczykowski 	{ "Laser tx power high alarm   (Channel %d)",
85*1b481fc3SMaciej Żenczykowski 	  CMIS_TX_PWR_AW_HALARM_OFFSET,
86*1b481fc3SMaciej Żenczykowski 	  CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_PWR_MON_MASK },
87*1b481fc3SMaciej Żenczykowski 	{ "Laser tx power low alarm    (Channel %d)",
88*1b481fc3SMaciej Żenczykowski 	  CMIS_TX_PWR_AW_LALARM_OFFSET,
89*1b481fc3SMaciej Żenczykowski 	  CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_PWR_MON_MASK },
90*1b481fc3SMaciej Żenczykowski 	{ "Laser tx power high warning (Channel %d)",
91*1b481fc3SMaciej Żenczykowski 	  CMIS_TX_PWR_AW_HWARN_OFFSET,
92*1b481fc3SMaciej Żenczykowski 	  CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_PWR_MON_MASK },
93*1b481fc3SMaciej Żenczykowski 	{ "Laser tx power low warning  (Channel %d)",
94*1b481fc3SMaciej Żenczykowski 	  CMIS_TX_PWR_AW_LWARN_OFFSET,
95*1b481fc3SMaciej Żenczykowski 	  CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_TX_PWR_MON_MASK },
96*1b481fc3SMaciej Żenczykowski 
97*1b481fc3SMaciej Żenczykowski 	{ "Laser rx power high alarm   (Channel %d)",
98*1b481fc3SMaciej Żenczykowski 	  CMIS_RX_PWR_AW_HALARM_OFFSET,
99*1b481fc3SMaciej Żenczykowski 	  CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_RX_PWR_MON_MASK },
100*1b481fc3SMaciej Żenczykowski 	{ "Laser rx power low alarm    (Channel %d)",
101*1b481fc3SMaciej Żenczykowski 	  CMIS_RX_PWR_AW_LALARM_OFFSET,
102*1b481fc3SMaciej Żenczykowski 	  CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_RX_PWR_MON_MASK },
103*1b481fc3SMaciej Żenczykowski 	{ "Laser rx power high warning (Channel %d)",
104*1b481fc3SMaciej Żenczykowski 	  CMIS_RX_PWR_AW_HWARN_OFFSET,
105*1b481fc3SMaciej Żenczykowski 	  CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_RX_PWR_MON_MASK },
106*1b481fc3SMaciej Żenczykowski 	{ "Laser rx power low warning  (Channel %d)",
107*1b481fc3SMaciej Żenczykowski 	  CMIS_RX_PWR_AW_LWARN_OFFSET,
108*1b481fc3SMaciej Żenczykowski 	  CMIS_DIAG_CHAN_ADVER_OFFSET, CMIS_RX_PWR_MON_MASK },
109*1b481fc3SMaciej Żenczykowski 
110*1b481fc3SMaciej Żenczykowski 	{ NULL, 0, 0, 0 },
111*1b481fc3SMaciej Żenczykowski };
112*1b481fc3SMaciej Żenczykowski 
cmis_show_identifier(const struct cmis_memory_map * map)113*1b481fc3SMaciej Żenczykowski static void cmis_show_identifier(const struct cmis_memory_map *map)
114*1b481fc3SMaciej Żenczykowski {
115*1b481fc3SMaciej Żenczykowski 	sff8024_show_identifier(map->lower_memory, CMIS_ID_OFFSET);
116*1b481fc3SMaciej Żenczykowski }
117*1b481fc3SMaciej Żenczykowski 
cmis_show_connector(const struct cmis_memory_map * map)118*1b481fc3SMaciej Żenczykowski static void cmis_show_connector(const struct cmis_memory_map *map)
119*1b481fc3SMaciej Żenczykowski {
120*1b481fc3SMaciej Żenczykowski 	sff8024_show_connector(map->page_00h, CMIS_CTOR_OFFSET);
121*1b481fc3SMaciej Żenczykowski }
122*1b481fc3SMaciej Żenczykowski 
cmis_show_oui(const struct cmis_memory_map * map)123*1b481fc3SMaciej Żenczykowski static void cmis_show_oui(const struct cmis_memory_map *map)
124*1b481fc3SMaciej Żenczykowski {
125*1b481fc3SMaciej Żenczykowski 	sff8024_show_oui(map->page_00h, CMIS_VENDOR_OUI_OFFSET);
126*1b481fc3SMaciej Żenczykowski }
127*1b481fc3SMaciej Żenczykowski 
128*1b481fc3SMaciej Żenczykowski /**
129*1b481fc3SMaciej Żenczykowski  * Print the revision compliance. Relevant documents:
130*1b481fc3SMaciej Żenczykowski  * [1] CMIS Rev. 3, pag. 45, section 1.7.2.1, Table 18
131*1b481fc3SMaciej Żenczykowski  * [2] CMIS Rev. 4, pag. 81, section 8.2.1, Table 8-2
132*1b481fc3SMaciej Żenczykowski  */
cmis_show_rev_compliance(const struct cmis_memory_map * map)133*1b481fc3SMaciej Żenczykowski static void cmis_show_rev_compliance(const struct cmis_memory_map *map)
134*1b481fc3SMaciej Żenczykowski {
135*1b481fc3SMaciej Żenczykowski 	__u8 rev = map->lower_memory[CMIS_REV_COMPLIANCE_OFFSET];
136*1b481fc3SMaciej Żenczykowski 	int major = (rev >> 4) & 0x0F;
137*1b481fc3SMaciej Żenczykowski 	int minor = rev & 0x0F;
138*1b481fc3SMaciej Żenczykowski 
139*1b481fc3SMaciej Żenczykowski 	printf("\t%-41s : Rev. %d.%d\n", "Revision compliance", major, minor);
140*1b481fc3SMaciej Żenczykowski }
141*1b481fc3SMaciej Żenczykowski 
142*1b481fc3SMaciej Żenczykowski static void
cmis_show_signals_one(const struct cmis_memory_map * map,const char * name,int off,int ioff,unsigned int imask)143*1b481fc3SMaciej Żenczykowski cmis_show_signals_one(const struct cmis_memory_map *map, const char *name,
144*1b481fc3SMaciej Żenczykowski 		      int off, int ioff, unsigned int imask)
145*1b481fc3SMaciej Żenczykowski {
146*1b481fc3SMaciej Żenczykowski 	unsigned int v;
147*1b481fc3SMaciej Żenczykowski 	int i;
148*1b481fc3SMaciej Żenczykowski 
149*1b481fc3SMaciej Żenczykowski 	if (!map->page_01h)
150*1b481fc3SMaciej Żenczykowski 		return;
151*1b481fc3SMaciej Żenczykowski 
152*1b481fc3SMaciej Żenczykowski 	v = 0;
153*1b481fc3SMaciej Żenczykowski 	for (i = 0; i < CMIS_MAX_BANKS && map->upper_memory[i][0x11]; i++)
154*1b481fc3SMaciej Żenczykowski 		v |= map->upper_memory[i][0x11][off] << (i * 8);
155*1b481fc3SMaciej Żenczykowski 
156*1b481fc3SMaciej Żenczykowski 	if (map->page_01h[ioff] & imask)
157*1b481fc3SMaciej Żenczykowski 		sff_show_lane_status(name, i * 8, "Yes", "No", v);
158*1b481fc3SMaciej Żenczykowski }
159*1b481fc3SMaciej Żenczykowski 
cmis_show_signals(const struct cmis_memory_map * map)160*1b481fc3SMaciej Żenczykowski static void cmis_show_signals(const struct cmis_memory_map *map)
161*1b481fc3SMaciej Żenczykowski {
162*1b481fc3SMaciej Żenczykowski 	cmis_show_signals_one(map, "Rx loss of signal", CMIS_RX_LOS_OFFSET,
163*1b481fc3SMaciej Żenczykowski 			      CMIS_DIAG_FLAGS_RX_OFFSET, CMIS_DIAG_FL_RX_LOS);
164*1b481fc3SMaciej Żenczykowski 	cmis_show_signals_one(map, "Tx loss of signal", CMIS_TX_LOS_OFFSET,
165*1b481fc3SMaciej Żenczykowski 			      CMIS_DIAG_FLAGS_TX_OFFSET, CMIS_DIAG_FL_TX_LOS);
166*1b481fc3SMaciej Żenczykowski 
167*1b481fc3SMaciej Żenczykowski 	cmis_show_signals_one(map, "Rx loss of lock", CMIS_RX_LOL_OFFSET,
168*1b481fc3SMaciej Żenczykowski 			      CMIS_DIAG_FLAGS_RX_OFFSET, CMIS_DIAG_FL_RX_LOL);
169*1b481fc3SMaciej Żenczykowski 	cmis_show_signals_one(map, "Tx loss of lock", CMIS_TX_LOL_OFFSET,
170*1b481fc3SMaciej Żenczykowski 			      CMIS_DIAG_FLAGS_TX_OFFSET, CMIS_DIAG_FL_TX_LOL);
171*1b481fc3SMaciej Żenczykowski 
172*1b481fc3SMaciej Żenczykowski 	cmis_show_signals_one(map, "Tx fault", CMIS_TX_FAIL_OFFSET,
173*1b481fc3SMaciej Żenczykowski 			      CMIS_DIAG_FLAGS_TX_OFFSET, CMIS_DIAG_FL_TX_FAIL);
174*1b481fc3SMaciej Żenczykowski 
175*1b481fc3SMaciej Żenczykowski 	cmis_show_signals_one(map, "Tx adaptive eq fault",
176*1b481fc3SMaciej Żenczykowski 			      CMIS_TX_EQ_FAIL_OFFSET, CMIS_DIAG_FLAGS_TX_OFFSET,
177*1b481fc3SMaciej Żenczykowski 			      CMIS_DIAG_FL_TX_ADAPTIVE_EQ_FAIL);
178*1b481fc3SMaciej Żenczykowski }
179*1b481fc3SMaciej Żenczykowski 
180*1b481fc3SMaciej Żenczykowski /**
181*1b481fc3SMaciej Żenczykowski  * Print information about the device's power consumption.
182*1b481fc3SMaciej Żenczykowski  * Relevant documents:
183*1b481fc3SMaciej Żenczykowski  * [1] CMIS Rev. 3, pag. 59, section 1.7.3.9, Table 30
184*1b481fc3SMaciej Żenczykowski  * [2] CMIS Rev. 4, pag. 94, section 8.3.9, Table 8-18
185*1b481fc3SMaciej Żenczykowski  * [3] QSFP-DD Hardware Rev 5.0, pag. 22, section 4.2.1
186*1b481fc3SMaciej Żenczykowski  */
cmis_show_power_info(const struct cmis_memory_map * map)187*1b481fc3SMaciej Żenczykowski static void cmis_show_power_info(const struct cmis_memory_map *map)
188*1b481fc3SMaciej Żenczykowski {
189*1b481fc3SMaciej Żenczykowski 	float max_power = 0.0f;
190*1b481fc3SMaciej Żenczykowski 	__u8 base_power = 0;
191*1b481fc3SMaciej Żenczykowski 	__u8 power_class;
192*1b481fc3SMaciej Żenczykowski 
193*1b481fc3SMaciej Żenczykowski 	/* Get the power class (first 3 most significat bytes) */
194*1b481fc3SMaciej Żenczykowski 	power_class = (map->page_00h[CMIS_PWR_CLASS_OFFSET] >> 5) & 0x07;
195*1b481fc3SMaciej Żenczykowski 
196*1b481fc3SMaciej Żenczykowski 	/* Get the base power in multiples of 0.25W */
197*1b481fc3SMaciej Żenczykowski 	base_power = map->page_00h[CMIS_PWR_MAX_POWER_OFFSET];
198*1b481fc3SMaciej Żenczykowski 	max_power = base_power * 0.25f;
199*1b481fc3SMaciej Żenczykowski 
200*1b481fc3SMaciej Żenczykowski 	printf("\t%-41s : %d\n", "Power class", power_class + 1);
201*1b481fc3SMaciej Żenczykowski 	printf("\t%-41s : %.02fW\n", "Max power", max_power);
202*1b481fc3SMaciej Żenczykowski }
203*1b481fc3SMaciej Żenczykowski 
204*1b481fc3SMaciej Żenczykowski /**
205*1b481fc3SMaciej Żenczykowski  * Print the cable assembly length, for both passive copper and active
206*1b481fc3SMaciej Żenczykowski  * optical or electrical cables. The base length (bits 5-0) must be
207*1b481fc3SMaciej Żenczykowski  * multiplied with the SMF length multiplier (bits 7-6) to obtain the
208*1b481fc3SMaciej Żenczykowski  * correct value. Relevant documents:
209*1b481fc3SMaciej Żenczykowski  * [1] CMIS Rev. 3, pag. 59, section 1.7.3.10, Table 31
210*1b481fc3SMaciej Żenczykowski  * [2] CMIS Rev. 4, pag. 94, section 8.3.10, Table 8-19
211*1b481fc3SMaciej Żenczykowski  */
cmis_show_cbl_asm_len(const struct cmis_memory_map * map)212*1b481fc3SMaciej Żenczykowski static void cmis_show_cbl_asm_len(const struct cmis_memory_map *map)
213*1b481fc3SMaciej Żenczykowski {
214*1b481fc3SMaciej Żenczykowski 	static const char *fn = "Cable assembly length";
215*1b481fc3SMaciej Żenczykowski 	float mul = 1.0f;
216*1b481fc3SMaciej Żenczykowski 	float val = 0.0f;
217*1b481fc3SMaciej Żenczykowski 
218*1b481fc3SMaciej Żenczykowski 	/* Check if max length */
219*1b481fc3SMaciej Żenczykowski 	if (map->page_00h[CMIS_CBL_ASM_LEN_OFFSET] == CMIS_6300M_MAX_LEN) {
220*1b481fc3SMaciej Żenczykowski 		printf("\t%-41s : > 6.3km\n", fn);
221*1b481fc3SMaciej Żenczykowski 		return;
222*1b481fc3SMaciej Żenczykowski 	}
223*1b481fc3SMaciej Żenczykowski 
224*1b481fc3SMaciej Żenczykowski 	/* Get the multiplier from the first two bits */
225*1b481fc3SMaciej Żenczykowski 	switch (map->page_00h[CMIS_CBL_ASM_LEN_OFFSET] & CMIS_LEN_MUL_MASK) {
226*1b481fc3SMaciej Żenczykowski 	case CMIS_MULTIPLIER_00:
227*1b481fc3SMaciej Żenczykowski 		mul = 0.1f;
228*1b481fc3SMaciej Żenczykowski 		break;
229*1b481fc3SMaciej Żenczykowski 	case CMIS_MULTIPLIER_01:
230*1b481fc3SMaciej Żenczykowski 		mul = 1.0f;
231*1b481fc3SMaciej Żenczykowski 		break;
232*1b481fc3SMaciej Żenczykowski 	case CMIS_MULTIPLIER_10:
233*1b481fc3SMaciej Żenczykowski 		mul = 10.0f;
234*1b481fc3SMaciej Żenczykowski 		break;
235*1b481fc3SMaciej Żenczykowski 	case CMIS_MULTIPLIER_11:
236*1b481fc3SMaciej Żenczykowski 		mul = 100.0f;
237*1b481fc3SMaciej Żenczykowski 		break;
238*1b481fc3SMaciej Żenczykowski 	default:
239*1b481fc3SMaciej Żenczykowski 		break;
240*1b481fc3SMaciej Żenczykowski 	}
241*1b481fc3SMaciej Żenczykowski 
242*1b481fc3SMaciej Żenczykowski 	/* Get base value from first 6 bits and multiply by mul */
243*1b481fc3SMaciej Żenczykowski 	val = (map->page_00h[CMIS_CBL_ASM_LEN_OFFSET] & CMIS_LEN_VAL_MASK);
244*1b481fc3SMaciej Żenczykowski 	val = (float)val * mul;
245*1b481fc3SMaciej Żenczykowski 	printf("\t%-41s : %0.2fm\n", fn, val);
246*1b481fc3SMaciej Żenczykowski }
247*1b481fc3SMaciej Żenczykowski 
248*1b481fc3SMaciej Żenczykowski /**
249*1b481fc3SMaciej Żenczykowski  * Print the length for SMF fiber. The base length (bits 5-0) must be
250*1b481fc3SMaciej Żenczykowski  * multiplied with the SMF length multiplier (bits 7-6) to obtain the
251*1b481fc3SMaciej Żenczykowski  * correct value. Relevant documents:
252*1b481fc3SMaciej Żenczykowski  * [1] CMIS Rev. 3, pag. 63, section 1.7.4.2, Table 39
253*1b481fc3SMaciej Żenczykowski  * [2] CMIS Rev. 4, pag. 99, section 8.4.2, Table 8-27
254*1b481fc3SMaciej Żenczykowski  */
cmis_print_smf_cbl_len(const struct cmis_memory_map * map)255*1b481fc3SMaciej Żenczykowski static void cmis_print_smf_cbl_len(const struct cmis_memory_map *map)
256*1b481fc3SMaciej Żenczykowski {
257*1b481fc3SMaciej Żenczykowski 	static const char *fn = "Length (SMF)";
258*1b481fc3SMaciej Żenczykowski 	float mul = 1.0f;
259*1b481fc3SMaciej Żenczykowski 	float val = 0.0f;
260*1b481fc3SMaciej Żenczykowski 
261*1b481fc3SMaciej Żenczykowski 	if (!map->page_01h)
262*1b481fc3SMaciej Żenczykowski 		return;
263*1b481fc3SMaciej Żenczykowski 
264*1b481fc3SMaciej Żenczykowski 	/* Get the multiplier from the first two bits */
265*1b481fc3SMaciej Żenczykowski 	switch (map->page_01h[CMIS_SMF_LEN_OFFSET] & CMIS_LEN_MUL_MASK) {
266*1b481fc3SMaciej Żenczykowski 	case CMIS_MULTIPLIER_00:
267*1b481fc3SMaciej Żenczykowski 		mul = 0.1f;
268*1b481fc3SMaciej Żenczykowski 		break;
269*1b481fc3SMaciej Żenczykowski 	case CMIS_MULTIPLIER_01:
270*1b481fc3SMaciej Żenczykowski 		mul = 1.0f;
271*1b481fc3SMaciej Żenczykowski 		break;
272*1b481fc3SMaciej Żenczykowski 	default:
273*1b481fc3SMaciej Żenczykowski 		break;
274*1b481fc3SMaciej Żenczykowski 	}
275*1b481fc3SMaciej Żenczykowski 
276*1b481fc3SMaciej Żenczykowski 	/* Get base value from first 6 bits and multiply by mul */
277*1b481fc3SMaciej Żenczykowski 	val = (map->page_01h[CMIS_SMF_LEN_OFFSET] & CMIS_LEN_VAL_MASK);
278*1b481fc3SMaciej Żenczykowski 	val = (float)val * mul;
279*1b481fc3SMaciej Żenczykowski 	printf("\t%-41s : %0.2fkm\n", fn, val);
280*1b481fc3SMaciej Żenczykowski }
281*1b481fc3SMaciej Żenczykowski 
282*1b481fc3SMaciej Żenczykowski /**
283*1b481fc3SMaciej Żenczykowski  * Print relevant signal integrity control properties. Relevant documents:
284*1b481fc3SMaciej Żenczykowski  * [1] CMIS Rev. 3, pag. 71, section 1.7.4.10, Table 46
285*1b481fc3SMaciej Żenczykowski  * [2] CMIS Rev. 4, pag. 105, section 8.4.10, Table 8-34
286*1b481fc3SMaciej Żenczykowski  */
cmis_show_sig_integrity(const struct cmis_memory_map * map)287*1b481fc3SMaciej Żenczykowski static void cmis_show_sig_integrity(const struct cmis_memory_map *map)
288*1b481fc3SMaciej Żenczykowski {
289*1b481fc3SMaciej Żenczykowski 	if (!map->page_01h)
290*1b481fc3SMaciej Żenczykowski 		return;
291*1b481fc3SMaciej Żenczykowski 
292*1b481fc3SMaciej Żenczykowski 	/* CDR Bypass control: 2nd bit from each byte */
293*1b481fc3SMaciej Żenczykowski 	printf("\t%-41s : ", "Tx CDR bypass control");
294*1b481fc3SMaciej Żenczykowski 	printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_TX_OFFSET] & 0x02));
295*1b481fc3SMaciej Żenczykowski 
296*1b481fc3SMaciej Żenczykowski 	printf("\t%-41s : ", "Rx CDR bypass control");
297*1b481fc3SMaciej Żenczykowski 	printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_RX_OFFSET] & 0x02));
298*1b481fc3SMaciej Żenczykowski 
299*1b481fc3SMaciej Żenczykowski 	/* CDR Implementation: 1st bit from each byte */
300*1b481fc3SMaciej Żenczykowski 	printf("\t%-41s : ", "Tx CDR");
301*1b481fc3SMaciej Żenczykowski 	printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_TX_OFFSET] & 0x01));
302*1b481fc3SMaciej Żenczykowski 
303*1b481fc3SMaciej Żenczykowski 	printf("\t%-41s : ", "Rx CDR");
304*1b481fc3SMaciej Żenczykowski 	printf("%s\n", YESNO(map->page_01h[CMIS_SIG_INTEG_RX_OFFSET] & 0x01));
305*1b481fc3SMaciej Żenczykowski }
306*1b481fc3SMaciej Żenczykowski 
307*1b481fc3SMaciej Żenczykowski /**
308*1b481fc3SMaciej Żenczykowski  * Print relevant media interface technology info. Relevant documents:
309*1b481fc3SMaciej Żenczykowski  * [1] CMIS Rev. 3
310*1b481fc3SMaciej Żenczykowski  * --> pag. 61, section 1.7.3.14, Table 36
311*1b481fc3SMaciej Żenczykowski  * --> pag. 64, section 1.7.4.3, 1.7.4.4
312*1b481fc3SMaciej Żenczykowski  * [2] CMIS Rev. 4
313*1b481fc3SMaciej Żenczykowski  * --> pag. 97, section 8.3.14, Table 8-24
314*1b481fc3SMaciej Żenczykowski  * --> pag. 98, section 8.4, Table 8-25
315*1b481fc3SMaciej Żenczykowski  * --> page 100, section 8.4.3, 8.4.4
316*1b481fc3SMaciej Żenczykowski  */
cmis_show_mit_compliance(const struct cmis_memory_map * map)317*1b481fc3SMaciej Żenczykowski static void cmis_show_mit_compliance(const struct cmis_memory_map *map)
318*1b481fc3SMaciej Żenczykowski {
319*1b481fc3SMaciej Żenczykowski 	static const char *cc = " (Copper cable,";
320*1b481fc3SMaciej Żenczykowski 
321*1b481fc3SMaciej Żenczykowski 	printf("\t%-41s : 0x%02x", "Transmitter technology",
322*1b481fc3SMaciej Żenczykowski 	       map->page_00h[CMIS_MEDIA_INTF_TECH_OFFSET]);
323*1b481fc3SMaciej Żenczykowski 
324*1b481fc3SMaciej Żenczykowski 	switch (map->page_00h[CMIS_MEDIA_INTF_TECH_OFFSET]) {
325*1b481fc3SMaciej Żenczykowski 	case CMIS_850_VCSEL:
326*1b481fc3SMaciej Żenczykowski 		printf(" (850 nm VCSEL)\n");
327*1b481fc3SMaciej Żenczykowski 		break;
328*1b481fc3SMaciej Żenczykowski 	case CMIS_1310_VCSEL:
329*1b481fc3SMaciej Żenczykowski 		printf(" (1310 nm VCSEL)\n");
330*1b481fc3SMaciej Żenczykowski 		break;
331*1b481fc3SMaciej Żenczykowski 	case CMIS_1550_VCSEL:
332*1b481fc3SMaciej Żenczykowski 		printf(" (1550 nm VCSEL)\n");
333*1b481fc3SMaciej Żenczykowski 		break;
334*1b481fc3SMaciej Żenczykowski 	case CMIS_1310_FP:
335*1b481fc3SMaciej Żenczykowski 		printf(" (1310 nm FP)\n");
336*1b481fc3SMaciej Żenczykowski 		break;
337*1b481fc3SMaciej Żenczykowski 	case CMIS_1310_DFB:
338*1b481fc3SMaciej Żenczykowski 		printf(" (1310 nm DFB)\n");
339*1b481fc3SMaciej Żenczykowski 		break;
340*1b481fc3SMaciej Żenczykowski 	case CMIS_1550_DFB:
341*1b481fc3SMaciej Żenczykowski 		printf(" (1550 nm DFB)\n");
342*1b481fc3SMaciej Żenczykowski 		break;
343*1b481fc3SMaciej Żenczykowski 	case CMIS_1310_EML:
344*1b481fc3SMaciej Żenczykowski 		printf(" (1310 nm EML)\n");
345*1b481fc3SMaciej Żenczykowski 		break;
346*1b481fc3SMaciej Żenczykowski 	case CMIS_1550_EML:
347*1b481fc3SMaciej Żenczykowski 		printf(" (1550 nm EML)\n");
348*1b481fc3SMaciej Żenczykowski 		break;
349*1b481fc3SMaciej Żenczykowski 	case CMIS_OTHERS:
350*1b481fc3SMaciej Żenczykowski 		printf(" (Others/Undefined)\n");
351*1b481fc3SMaciej Żenczykowski 		break;
352*1b481fc3SMaciej Żenczykowski 	case CMIS_1490_DFB:
353*1b481fc3SMaciej Żenczykowski 		printf(" (1490 nm DFB)\n");
354*1b481fc3SMaciej Żenczykowski 		break;
355*1b481fc3SMaciej Żenczykowski 	case CMIS_COPPER_UNEQUAL:
356*1b481fc3SMaciej Żenczykowski 		printf("%s unequalized)\n", cc);
357*1b481fc3SMaciej Żenczykowski 		break;
358*1b481fc3SMaciej Żenczykowski 	case CMIS_COPPER_PASS_EQUAL:
359*1b481fc3SMaciej Żenczykowski 		printf("%s passive equalized)\n", cc);
360*1b481fc3SMaciej Żenczykowski 		break;
361*1b481fc3SMaciej Żenczykowski 	case CMIS_COPPER_NF_EQUAL:
362*1b481fc3SMaciej Żenczykowski 		printf("%s near and far end limiting active equalizers)\n", cc);
363*1b481fc3SMaciej Żenczykowski 		break;
364*1b481fc3SMaciej Żenczykowski 	case CMIS_COPPER_F_EQUAL:
365*1b481fc3SMaciej Żenczykowski 		printf("%s far end limiting active equalizers)\n", cc);
366*1b481fc3SMaciej Żenczykowski 		break;
367*1b481fc3SMaciej Żenczykowski 	case CMIS_COPPER_N_EQUAL:
368*1b481fc3SMaciej Żenczykowski 		printf("%s near end limiting active equalizers)\n", cc);
369*1b481fc3SMaciej Żenczykowski 		break;
370*1b481fc3SMaciej Żenczykowski 	case CMIS_COPPER_LINEAR_EQUAL:
371*1b481fc3SMaciej Żenczykowski 		printf("%s linear active equalizers)\n", cc);
372*1b481fc3SMaciej Żenczykowski 		break;
373*1b481fc3SMaciej Żenczykowski 	}
374*1b481fc3SMaciej Żenczykowski 
375*1b481fc3SMaciej Żenczykowski 	if (map->page_00h[CMIS_MEDIA_INTF_TECH_OFFSET] >= CMIS_COPPER_UNEQUAL) {
376*1b481fc3SMaciej Żenczykowski 		printf("\t%-41s : %udb\n", "Attenuation at 5GHz",
377*1b481fc3SMaciej Żenczykowski 		       map->page_00h[CMIS_COPPER_ATT_5GHZ]);
378*1b481fc3SMaciej Żenczykowski 		printf("\t%-41s : %udb\n", "Attenuation at 7GHz",
379*1b481fc3SMaciej Żenczykowski 		       map->page_00h[CMIS_COPPER_ATT_7GHZ]);
380*1b481fc3SMaciej Żenczykowski 		printf("\t%-41s : %udb\n", "Attenuation at 12.9GHz",
381*1b481fc3SMaciej Żenczykowski 		       map->page_00h[CMIS_COPPER_ATT_12P9GHZ]);
382*1b481fc3SMaciej Żenczykowski 		printf("\t%-41s : %udb\n", "Attenuation at 25.8GHz",
383*1b481fc3SMaciej Żenczykowski 		       map->page_00h[CMIS_COPPER_ATT_25P8GHZ]);
384*1b481fc3SMaciej Żenczykowski 	} else if (map->page_01h) {
385*1b481fc3SMaciej Żenczykowski 		printf("\t%-41s : %.3lfnm\n", "Laser wavelength",
386*1b481fc3SMaciej Żenczykowski 		       (((map->page_01h[CMIS_NOM_WAVELENGTH_MSB] << 8) |
387*1b481fc3SMaciej Żenczykowski 			  map->page_01h[CMIS_NOM_WAVELENGTH_LSB]) * 0.05));
388*1b481fc3SMaciej Żenczykowski 		printf("\t%-41s : %.3lfnm\n", "Laser wavelength tolerance",
389*1b481fc3SMaciej Żenczykowski 		       (((map->page_01h[CMIS_WAVELENGTH_TOL_MSB] << 8) |
390*1b481fc3SMaciej Żenczykowski 			  map->page_01h[CMIS_WAVELENGTH_TOL_LSB]) * 0.005));
391*1b481fc3SMaciej Żenczykowski 	}
392*1b481fc3SMaciej Żenczykowski }
393*1b481fc3SMaciej Żenczykowski 
394*1b481fc3SMaciej Żenczykowski /**
395*1b481fc3SMaciej Żenczykowski  * Print relevant info about the maximum supported fiber media length
396*1b481fc3SMaciej Żenczykowski  * for each type of fiber media at the maximum module-supported bit rate.
397*1b481fc3SMaciej Żenczykowski  * Relevant documents:
398*1b481fc3SMaciej Żenczykowski  * [1] CMIS Rev. 3, page 64, section 1.7.4.2, Table 39
399*1b481fc3SMaciej Żenczykowski  * [2] CMIS Rev. 4, page 99, section 8.4.2, Table 8-27
400*1b481fc3SMaciej Żenczykowski  */
cmis_show_link_len(const struct cmis_memory_map * map)401*1b481fc3SMaciej Żenczykowski static void cmis_show_link_len(const struct cmis_memory_map *map)
402*1b481fc3SMaciej Żenczykowski {
403*1b481fc3SMaciej Żenczykowski 	cmis_print_smf_cbl_len(map);
404*1b481fc3SMaciej Żenczykowski 	if (!map->page_01h)
405*1b481fc3SMaciej Żenczykowski 		return;
406*1b481fc3SMaciej Żenczykowski 	sff_show_value_with_unit(map->page_01h, CMIS_OM5_LEN_OFFSET,
407*1b481fc3SMaciej Żenczykowski 				 "Length (OM5)", 2, "m");
408*1b481fc3SMaciej Żenczykowski 	sff_show_value_with_unit(map->page_01h, CMIS_OM4_LEN_OFFSET,
409*1b481fc3SMaciej Żenczykowski 				 "Length (OM4)", 2, "m");
410*1b481fc3SMaciej Żenczykowski 	sff_show_value_with_unit(map->page_01h, CMIS_OM3_LEN_OFFSET,
411*1b481fc3SMaciej Żenczykowski 				 "Length (OM3 50/125um)", 2, "m");
412*1b481fc3SMaciej Żenczykowski 	sff_show_value_with_unit(map->page_01h, CMIS_OM2_LEN_OFFSET,
413*1b481fc3SMaciej Żenczykowski 				 "Length (OM2 50/125um)", 1, "m");
414*1b481fc3SMaciej Żenczykowski }
415*1b481fc3SMaciej Żenczykowski 
416*1b481fc3SMaciej Żenczykowski /**
417*1b481fc3SMaciej Żenczykowski  * Show relevant information about the vendor. Relevant documents:
418*1b481fc3SMaciej Żenczykowski  * [1] CMIS Rev. 3, page 56, section 1.7.3, Table 27
419*1b481fc3SMaciej Żenczykowski  * [2] CMIS Rev. 4, page 91, section 8.2, Table 8-15
420*1b481fc3SMaciej Żenczykowski  */
cmis_show_vendor_info(const struct cmis_memory_map * map)421*1b481fc3SMaciej Żenczykowski static void cmis_show_vendor_info(const struct cmis_memory_map *map)
422*1b481fc3SMaciej Żenczykowski {
423*1b481fc3SMaciej Żenczykowski 	const char *clei;
424*1b481fc3SMaciej Żenczykowski 
425*1b481fc3SMaciej Żenczykowski 	sff_show_ascii(map->page_00h, CMIS_VENDOR_NAME_START_OFFSET,
426*1b481fc3SMaciej Żenczykowski 		       CMIS_VENDOR_NAME_END_OFFSET, "Vendor name");
427*1b481fc3SMaciej Żenczykowski 	cmis_show_oui(map);
428*1b481fc3SMaciej Żenczykowski 	sff_show_ascii(map->page_00h, CMIS_VENDOR_PN_START_OFFSET,
429*1b481fc3SMaciej Żenczykowski 		       CMIS_VENDOR_PN_END_OFFSET, "Vendor PN");
430*1b481fc3SMaciej Żenczykowski 	sff_show_ascii(map->page_00h, CMIS_VENDOR_REV_START_OFFSET,
431*1b481fc3SMaciej Żenczykowski 		       CMIS_VENDOR_REV_END_OFFSET, "Vendor rev");
432*1b481fc3SMaciej Żenczykowski 	sff_show_ascii(map->page_00h, CMIS_VENDOR_SN_START_OFFSET,
433*1b481fc3SMaciej Żenczykowski 		       CMIS_VENDOR_SN_END_OFFSET, "Vendor SN");
434*1b481fc3SMaciej Żenczykowski 	sff_show_ascii(map->page_00h, CMIS_DATE_YEAR_OFFSET,
435*1b481fc3SMaciej Żenczykowski 		       CMIS_DATE_VENDOR_LOT_OFFSET + 1, "Date code");
436*1b481fc3SMaciej Żenczykowski 
437*1b481fc3SMaciej Żenczykowski 	clei = (const char *)(map->page_00h + CMIS_CLEI_START_OFFSET);
438*1b481fc3SMaciej Żenczykowski 	if (*clei && strncmp(clei, CMIS_CLEI_BLANK, CMIS_CLEI_LEN))
439*1b481fc3SMaciej Żenczykowski 		sff_show_ascii(map->page_00h, CMIS_CLEI_START_OFFSET,
440*1b481fc3SMaciej Żenczykowski 			       CMIS_CLEI_END_OFFSET, "CLEI code");
441*1b481fc3SMaciej Żenczykowski }
442*1b481fc3SMaciej Żenczykowski 
443*1b481fc3SMaciej Żenczykowski /* Print the current Module State. Relevant documents:
444*1b481fc3SMaciej Żenczykowski  * [1] CMIS Rev. 5, pag. 57, section 6.3.2.2, Figure 6-3
445*1b481fc3SMaciej Żenczykowski  * [2] CMIS Rev. 5, pag. 60, section 6.3.2.3, Figure 6-4
446*1b481fc3SMaciej Żenczykowski  * [3] CMIS Rev. 5, pag. 107, section 8.2.2, Table 8-6
447*1b481fc3SMaciej Żenczykowski  */
cmis_show_mod_state(const struct cmis_memory_map * map)448*1b481fc3SMaciej Żenczykowski static void cmis_show_mod_state(const struct cmis_memory_map *map)
449*1b481fc3SMaciej Żenczykowski {
450*1b481fc3SMaciej Żenczykowski 	__u8 mod_state;
451*1b481fc3SMaciej Żenczykowski 
452*1b481fc3SMaciej Żenczykowski 	mod_state = (map->lower_memory[CMIS_MODULE_STATE_OFFSET] &
453*1b481fc3SMaciej Żenczykowski 		     CMIS_MODULE_STATE_MASK) >> 1;
454*1b481fc3SMaciej Żenczykowski 	printf("\t%-41s : 0x%02x", "Module State", mod_state);
455*1b481fc3SMaciej Żenczykowski 	switch (mod_state) {
456*1b481fc3SMaciej Żenczykowski 	case CMIS_MODULE_STATE_MODULE_LOW_PWR:
457*1b481fc3SMaciej Żenczykowski 		printf(" (ModuleLowPwr)\n");
458*1b481fc3SMaciej Żenczykowski 		break;
459*1b481fc3SMaciej Żenczykowski 	case CMIS_MODULE_STATE_MODULE_PWR_UP:
460*1b481fc3SMaciej Żenczykowski 		printf(" (ModulePwrUp)\n");
461*1b481fc3SMaciej Żenczykowski 		break;
462*1b481fc3SMaciej Żenczykowski 	case CMIS_MODULE_STATE_MODULE_READY:
463*1b481fc3SMaciej Żenczykowski 		printf(" (ModuleReady)\n");
464*1b481fc3SMaciej Żenczykowski 		break;
465*1b481fc3SMaciej Żenczykowski 	case CMIS_MODULE_STATE_MODULE_PWR_DN:
466*1b481fc3SMaciej Żenczykowski 		printf(" (ModulePwrDn)\n");
467*1b481fc3SMaciej Żenczykowski 		break;
468*1b481fc3SMaciej Żenczykowski 	case CMIS_MODULE_STATE_MODULE_FAULT:
469*1b481fc3SMaciej Żenczykowski 		printf(" (ModuleFault)\n");
470*1b481fc3SMaciej Żenczykowski 		break;
471*1b481fc3SMaciej Żenczykowski 	default:
472*1b481fc3SMaciej Żenczykowski 		printf(" (reserved or unknown)\n");
473*1b481fc3SMaciej Żenczykowski 		break;
474*1b481fc3SMaciej Żenczykowski 	}
475*1b481fc3SMaciej Żenczykowski }
476*1b481fc3SMaciej Żenczykowski 
477*1b481fc3SMaciej Żenczykowski /* Print the Module Fault Information. Relevant documents:
478*1b481fc3SMaciej Żenczykowski  * [1] CMIS Rev. 5, pag. 64, section 6.3.2.12
479*1b481fc3SMaciej Żenczykowski  * [2] CMIS Rev. 5, pag. 115, section 8.2.10, Table 8-15
480*1b481fc3SMaciej Żenczykowski  */
cmis_show_mod_fault_cause(const struct cmis_memory_map * map)481*1b481fc3SMaciej Żenczykowski static void cmis_show_mod_fault_cause(const struct cmis_memory_map *map)
482*1b481fc3SMaciej Żenczykowski {
483*1b481fc3SMaciej Żenczykowski 	__u8 mod_state, fault_cause;
484*1b481fc3SMaciej Żenczykowski 
485*1b481fc3SMaciej Żenczykowski 	mod_state = (map->lower_memory[CMIS_MODULE_STATE_OFFSET] &
486*1b481fc3SMaciej Żenczykowski 		     CMIS_MODULE_STATE_MASK) >> 1;
487*1b481fc3SMaciej Żenczykowski 	if (mod_state != CMIS_MODULE_STATE_MODULE_FAULT)
488*1b481fc3SMaciej Żenczykowski 		return;
489*1b481fc3SMaciej Żenczykowski 
490*1b481fc3SMaciej Żenczykowski 	fault_cause = map->lower_memory[CMIS_MODULE_FAULT_OFFSET];
491*1b481fc3SMaciej Żenczykowski 	printf("\t%-41s : 0x%02x", "Module Fault Cause", fault_cause);
492*1b481fc3SMaciej Żenczykowski 	switch (fault_cause) {
493*1b481fc3SMaciej Żenczykowski 	case CMIS_MODULE_FAULT_NO_FAULT:
494*1b481fc3SMaciej Żenczykowski 		printf(" (No fault detected / not supported)\n");
495*1b481fc3SMaciej Żenczykowski 		break;
496*1b481fc3SMaciej Żenczykowski 	case CMIS_MODULE_FAULT_TEC_RUNAWAY:
497*1b481fc3SMaciej Żenczykowski 		printf(" (TEC runaway)\n");
498*1b481fc3SMaciej Żenczykowski 		break;
499*1b481fc3SMaciej Żenczykowski 	case CMIS_MODULE_FAULT_DATA_MEM_CORRUPTED:
500*1b481fc3SMaciej Żenczykowski 		printf(" (Data memory corrupted)\n");
501*1b481fc3SMaciej Żenczykowski 		break;
502*1b481fc3SMaciej Żenczykowski 	case CMIS_MODULE_FAULT_PROG_MEM_CORRUPTED:
503*1b481fc3SMaciej Żenczykowski 		printf(" (Program memory corrupted)\n");
504*1b481fc3SMaciej Żenczykowski 		break;
505*1b481fc3SMaciej Żenczykowski 	default:
506*1b481fc3SMaciej Żenczykowski 		printf(" (reserved or unknown)\n");
507*1b481fc3SMaciej Żenczykowski 		break;
508*1b481fc3SMaciej Żenczykowski 	}
509*1b481fc3SMaciej Żenczykowski }
510*1b481fc3SMaciej Żenczykowski 
511*1b481fc3SMaciej Żenczykowski /* Print the current Module-Level Controls. Relevant documents:
512*1b481fc3SMaciej Żenczykowski  * [1] CMIS Rev. 5, pag. 58, section 6.3.2.2, Table 6-12
513*1b481fc3SMaciej Żenczykowski  * [2] CMIS Rev. 5, pag. 111, section 8.2.6, Table 8-10
514*1b481fc3SMaciej Żenczykowski  */
cmis_show_mod_lvl_controls(const struct cmis_memory_map * map)515*1b481fc3SMaciej Żenczykowski static void cmis_show_mod_lvl_controls(const struct cmis_memory_map *map)
516*1b481fc3SMaciej Żenczykowski {
517*1b481fc3SMaciej Żenczykowski 	printf("\t%-41s : ", "LowPwrAllowRequestHW");
518*1b481fc3SMaciej Żenczykowski 	printf("%s\n", ONOFF(map->lower_memory[CMIS_MODULE_CONTROL_OFFSET] &
519*1b481fc3SMaciej Żenczykowski 			     CMIS_LOW_PWR_ALLOW_REQUEST_HW_MASK));
520*1b481fc3SMaciej Żenczykowski 	printf("\t%-41s : ", "LowPwrRequestSW");
521*1b481fc3SMaciej Żenczykowski 	printf("%s\n", ONOFF(map->lower_memory[CMIS_MODULE_CONTROL_OFFSET] &
522*1b481fc3SMaciej Żenczykowski 			     CMIS_LOW_PWR_REQUEST_SW_MASK));
523*1b481fc3SMaciej Żenczykowski }
524*1b481fc3SMaciej Żenczykowski 
cmis_parse_dom_power_type(const struct cmis_memory_map * map,struct sff_diags * sd)525*1b481fc3SMaciej Żenczykowski static void cmis_parse_dom_power_type(const struct cmis_memory_map *map,
526*1b481fc3SMaciej Żenczykowski 				      struct sff_diags *sd)
527*1b481fc3SMaciej Żenczykowski {
528*1b481fc3SMaciej Żenczykowski 	sd->rx_power_type = map->page_01h[CMIS_DIAG_TYPE_OFFSET] &
529*1b481fc3SMaciej Żenczykowski 			    CMIS_RX_PWR_TYPE_MASK;
530*1b481fc3SMaciej Żenczykowski 	sd->tx_power_type = map->page_01h[CMIS_DIAG_CHAN_ADVER_OFFSET] &
531*1b481fc3SMaciej Żenczykowski 			    CMIS_TX_PWR_MON_MASK;
532*1b481fc3SMaciej Żenczykowski }
533*1b481fc3SMaciej Żenczykowski 
cmis_parse_dom_mod_lvl_monitors(const struct cmis_memory_map * map,struct sff_diags * sd)534*1b481fc3SMaciej Żenczykowski static void cmis_parse_dom_mod_lvl_monitors(const struct cmis_memory_map *map,
535*1b481fc3SMaciej Żenczykowski 					    struct sff_diags *sd)
536*1b481fc3SMaciej Żenczykowski {
537*1b481fc3SMaciej Żenczykowski 	sd->sfp_voltage[MCURR] = OFFSET_TO_U16_PTR(map->lower_memory,
538*1b481fc3SMaciej Żenczykowski 						   CMIS_CURR_VCC_OFFSET);
539*1b481fc3SMaciej Żenczykowski 	sd->sfp_temp[MCURR] = (__s16)OFFSET_TO_U16_PTR(map->lower_memory,
540*1b481fc3SMaciej Żenczykowski 						       CMIS_CURR_TEMP_OFFSET);
541*1b481fc3SMaciej Żenczykowski }
542*1b481fc3SMaciej Żenczykowski 
cmis_parse_dom_mod_lvl_thresh(const struct cmis_memory_map * map,struct sff_diags * sd)543*1b481fc3SMaciej Żenczykowski static void cmis_parse_dom_mod_lvl_thresh(const struct cmis_memory_map *map,
544*1b481fc3SMaciej Żenczykowski 					  struct sff_diags *sd)
545*1b481fc3SMaciej Żenczykowski {
546*1b481fc3SMaciej Żenczykowski 	/* Page is not present in IOCTL path. */
547*1b481fc3SMaciej Żenczykowski 	if (!map->page_02h)
548*1b481fc3SMaciej Żenczykowski 		return;
549*1b481fc3SMaciej Żenczykowski 	sd->supports_alarms = 1;
550*1b481fc3SMaciej Żenczykowski 
551*1b481fc3SMaciej Żenczykowski 	sd->sfp_voltage[HALRM] = OFFSET_TO_U16_PTR(map->page_02h,
552*1b481fc3SMaciej Żenczykowski 						   CMIS_VCC_HALRM_OFFSET);
553*1b481fc3SMaciej Żenczykowski 	sd->sfp_voltage[LALRM] = OFFSET_TO_U16_PTR(map->page_02h,
554*1b481fc3SMaciej Żenczykowski 						   CMIS_VCC_LALRM_OFFSET);
555*1b481fc3SMaciej Żenczykowski 	sd->sfp_voltage[HWARN] = OFFSET_TO_U16_PTR(map->page_02h,
556*1b481fc3SMaciej Żenczykowski 						   CMIS_VCC_HWARN_OFFSET);
557*1b481fc3SMaciej Żenczykowski 	sd->sfp_voltage[LWARN] = OFFSET_TO_U16_PTR(map->page_02h,
558*1b481fc3SMaciej Żenczykowski 						   CMIS_VCC_LWARN_OFFSET);
559*1b481fc3SMaciej Żenczykowski 
560*1b481fc3SMaciej Żenczykowski 	sd->sfp_temp[HALRM] = (__s16)OFFSET_TO_U16_PTR(map->page_02h,
561*1b481fc3SMaciej Żenczykowski 						       CMIS_TEMP_HALRM_OFFSET);
562*1b481fc3SMaciej Żenczykowski 	sd->sfp_temp[LALRM] = (__s16)OFFSET_TO_U16_PTR(map->page_02h,
563*1b481fc3SMaciej Żenczykowski 						       CMIS_TEMP_LALRM_OFFSET);
564*1b481fc3SMaciej Żenczykowski 	sd->sfp_temp[HWARN] = (__s16)OFFSET_TO_U16_PTR(map->page_02h,
565*1b481fc3SMaciej Żenczykowski 						       CMIS_TEMP_HWARN_OFFSET);
566*1b481fc3SMaciej Żenczykowski 	sd->sfp_temp[LWARN] = (__s16)OFFSET_TO_U16_PTR(map->page_02h,
567*1b481fc3SMaciej Żenczykowski 						       CMIS_TEMP_LWARN_OFFSET);
568*1b481fc3SMaciej Żenczykowski }
569*1b481fc3SMaciej Żenczykowski 
cmis_tx_bias_mul(const struct cmis_memory_map * map)570*1b481fc3SMaciej Żenczykowski static __u8 cmis_tx_bias_mul(const struct cmis_memory_map *map)
571*1b481fc3SMaciej Żenczykowski {
572*1b481fc3SMaciej Żenczykowski 	switch (map->page_01h[CMIS_DIAG_CHAN_ADVER_OFFSET] &
573*1b481fc3SMaciej Żenczykowski 		CMIS_TX_BIAS_MUL_MASK) {
574*1b481fc3SMaciej Żenczykowski 	case CMIS_TX_BIAS_MUL_1:
575*1b481fc3SMaciej Żenczykowski 		return 0;
576*1b481fc3SMaciej Żenczykowski 	case CMIS_TX_BIAS_MUL_2:
577*1b481fc3SMaciej Żenczykowski 		return 1;
578*1b481fc3SMaciej Żenczykowski 	case CMIS_TX_BIAS_MUL_4:
579*1b481fc3SMaciej Żenczykowski 		return 2;
580*1b481fc3SMaciej Żenczykowski 	}
581*1b481fc3SMaciej Żenczykowski 
582*1b481fc3SMaciej Żenczykowski 	return 0;
583*1b481fc3SMaciej Żenczykowski }
584*1b481fc3SMaciej Żenczykowski 
585*1b481fc3SMaciej Żenczykowski static void
cmis_parse_dom_chan_lvl_monitors_bank(const struct cmis_memory_map * map,struct sff_diags * sd,int bank)586*1b481fc3SMaciej Żenczykowski cmis_parse_dom_chan_lvl_monitors_bank(const struct cmis_memory_map *map,
587*1b481fc3SMaciej Żenczykowski 				      struct sff_diags *sd, int bank)
588*1b481fc3SMaciej Żenczykowski {
589*1b481fc3SMaciej Żenczykowski 	const __u8 *page_11h = map->upper_memory[bank][0x11];
590*1b481fc3SMaciej Żenczykowski 	int i;
591*1b481fc3SMaciej Żenczykowski 
592*1b481fc3SMaciej Żenczykowski 	if (!page_11h)
593*1b481fc3SMaciej Żenczykowski 		return;
594*1b481fc3SMaciej Żenczykowski 
595*1b481fc3SMaciej Żenczykowski 	for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) {
596*1b481fc3SMaciej Żenczykowski 		__u8 tx_bias_offset, rx_power_offset, tx_power_offset;
597*1b481fc3SMaciej Żenczykowski 		int chan = bank * CMIS_CHANNELS_PER_BANK + i;
598*1b481fc3SMaciej Żenczykowski 		__u8 bias_mul = cmis_tx_bias_mul(map);
599*1b481fc3SMaciej Żenczykowski 
600*1b481fc3SMaciej Żenczykowski 		tx_bias_offset = CMIS_TX_BIAS_OFFSET + i * sizeof(__u16);
601*1b481fc3SMaciej Żenczykowski 		rx_power_offset = CMIS_RX_PWR_OFFSET + i * sizeof(__u16);
602*1b481fc3SMaciej Żenczykowski 		tx_power_offset = CMIS_TX_PWR_OFFSET + i * sizeof(__u16);
603*1b481fc3SMaciej Żenczykowski 
604*1b481fc3SMaciej Żenczykowski 		sd->scd[chan].bias_cur = OFFSET_TO_U16_PTR(page_11h,
605*1b481fc3SMaciej Żenczykowski 							   tx_bias_offset);
606*1b481fc3SMaciej Żenczykowski 		sd->scd[chan].bias_cur >>= bias_mul;
607*1b481fc3SMaciej Żenczykowski 		sd->scd[chan].rx_power = OFFSET_TO_U16_PTR(page_11h,
608*1b481fc3SMaciej Żenczykowski 							   rx_power_offset);
609*1b481fc3SMaciej Żenczykowski 		sd->scd[chan].tx_power = OFFSET_TO_U16_PTR(page_11h,
610*1b481fc3SMaciej Żenczykowski 							   tx_power_offset);
611*1b481fc3SMaciej Żenczykowski 	}
612*1b481fc3SMaciej Żenczykowski }
613*1b481fc3SMaciej Żenczykowski 
cmis_parse_dom_chan_lvl_monitors(const struct cmis_memory_map * map,struct sff_diags * sd)614*1b481fc3SMaciej Żenczykowski static void cmis_parse_dom_chan_lvl_monitors(const struct cmis_memory_map *map,
615*1b481fc3SMaciej Żenczykowski 					     struct sff_diags *sd)
616*1b481fc3SMaciej Żenczykowski {
617*1b481fc3SMaciej Żenczykowski 	int i;
618*1b481fc3SMaciej Żenczykowski 
619*1b481fc3SMaciej Żenczykowski 	for (i = 0; i < CMIS_MAX_BANKS; i++)
620*1b481fc3SMaciej Żenczykowski 		cmis_parse_dom_chan_lvl_monitors_bank(map, sd, i);
621*1b481fc3SMaciej Żenczykowski }
622*1b481fc3SMaciej Żenczykowski 
cmis_parse_dom_chan_lvl_thresh(const struct cmis_memory_map * map,struct sff_diags * sd)623*1b481fc3SMaciej Żenczykowski static void cmis_parse_dom_chan_lvl_thresh(const struct cmis_memory_map *map,
624*1b481fc3SMaciej Żenczykowski 					   struct sff_diags *sd)
625*1b481fc3SMaciej Żenczykowski {
626*1b481fc3SMaciej Żenczykowski 	__u8 bias_mul = cmis_tx_bias_mul(map);
627*1b481fc3SMaciej Żenczykowski 
628*1b481fc3SMaciej Żenczykowski 	if (!map->page_02h)
629*1b481fc3SMaciej Żenczykowski 		return;
630*1b481fc3SMaciej Żenczykowski 
631*1b481fc3SMaciej Żenczykowski 	sd->bias_cur[HALRM] = OFFSET_TO_U16_PTR(map->page_02h,
632*1b481fc3SMaciej Żenczykowski 						CMIS_TX_BIAS_HALRM_OFFSET);
633*1b481fc3SMaciej Żenczykowski 	sd->bias_cur[HALRM] >>= bias_mul;
634*1b481fc3SMaciej Żenczykowski 	sd->bias_cur[LALRM] = OFFSET_TO_U16_PTR(map->page_02h,
635*1b481fc3SMaciej Żenczykowski 						CMIS_TX_BIAS_LALRM_OFFSET);
636*1b481fc3SMaciej Żenczykowski 	sd->bias_cur[LALRM] >>= bias_mul;
637*1b481fc3SMaciej Żenczykowski 	sd->bias_cur[HWARN] = OFFSET_TO_U16_PTR(map->page_02h,
638*1b481fc3SMaciej Żenczykowski 						CMIS_TX_BIAS_HWARN_OFFSET);
639*1b481fc3SMaciej Żenczykowski 	sd->bias_cur[HWARN] >>= bias_mul;
640*1b481fc3SMaciej Żenczykowski 	sd->bias_cur[LWARN] = OFFSET_TO_U16_PTR(map->page_02h,
641*1b481fc3SMaciej Żenczykowski 						CMIS_TX_BIAS_LWARN_OFFSET);
642*1b481fc3SMaciej Żenczykowski 	sd->bias_cur[LWARN] >>= bias_mul;
643*1b481fc3SMaciej Żenczykowski 
644*1b481fc3SMaciej Żenczykowski 	sd->tx_power[HALRM] = OFFSET_TO_U16_PTR(map->page_02h,
645*1b481fc3SMaciej Żenczykowski 						CMIS_TX_PWR_HALRM_OFFSET);
646*1b481fc3SMaciej Żenczykowski 	sd->tx_power[LALRM] = OFFSET_TO_U16_PTR(map->page_02h,
647*1b481fc3SMaciej Żenczykowski 						CMIS_TX_PWR_LALRM_OFFSET);
648*1b481fc3SMaciej Żenczykowski 	sd->tx_power[HWARN] = OFFSET_TO_U16_PTR(map->page_02h,
649*1b481fc3SMaciej Żenczykowski 						CMIS_TX_PWR_HWARN_OFFSET);
650*1b481fc3SMaciej Żenczykowski 	sd->tx_power[LWARN] = OFFSET_TO_U16_PTR(map->page_02h,
651*1b481fc3SMaciej Żenczykowski 						CMIS_TX_PWR_LWARN_OFFSET);
652*1b481fc3SMaciej Żenczykowski 
653*1b481fc3SMaciej Żenczykowski 	sd->rx_power[HALRM] = OFFSET_TO_U16_PTR(map->page_02h,
654*1b481fc3SMaciej Żenczykowski 						CMIS_RX_PWR_HALRM_OFFSET);
655*1b481fc3SMaciej Żenczykowski 	sd->rx_power[LALRM] = OFFSET_TO_U16_PTR(map->page_02h,
656*1b481fc3SMaciej Żenczykowski 						CMIS_RX_PWR_LALRM_OFFSET);
657*1b481fc3SMaciej Żenczykowski 	sd->rx_power[HWARN] = OFFSET_TO_U16_PTR(map->page_02h,
658*1b481fc3SMaciej Żenczykowski 						CMIS_RX_PWR_HWARN_OFFSET);
659*1b481fc3SMaciej Żenczykowski 	sd->rx_power[LWARN] = OFFSET_TO_U16_PTR(map->page_02h,
660*1b481fc3SMaciej Żenczykowski 						CMIS_RX_PWR_LWARN_OFFSET);
661*1b481fc3SMaciej Żenczykowski }
662*1b481fc3SMaciej Żenczykowski 
cmis_parse_dom(const struct cmis_memory_map * map,struct sff_diags * sd)663*1b481fc3SMaciej Żenczykowski static void cmis_parse_dom(const struct cmis_memory_map *map,
664*1b481fc3SMaciej Żenczykowski 			   struct sff_diags *sd)
665*1b481fc3SMaciej Żenczykowski {
666*1b481fc3SMaciej Żenczykowski 	cmis_parse_dom_power_type(map, sd);
667*1b481fc3SMaciej Żenczykowski 	cmis_parse_dom_mod_lvl_monitors(map, sd);
668*1b481fc3SMaciej Żenczykowski 	cmis_parse_dom_mod_lvl_thresh(map, sd);
669*1b481fc3SMaciej Żenczykowski 	cmis_parse_dom_chan_lvl_monitors(map, sd);
670*1b481fc3SMaciej Żenczykowski 	cmis_parse_dom_chan_lvl_thresh(map, sd);
671*1b481fc3SMaciej Żenczykowski }
672*1b481fc3SMaciej Żenczykowski 
673*1b481fc3SMaciej Żenczykowski /* Print module-level monitoring values. Relevant documents:
674*1b481fc3SMaciej Żenczykowski  * [1] CMIS Rev. 5, page 110, section 8.2.5, Table 8-9
675*1b481fc3SMaciej Żenczykowski  */
cmis_show_dom_mod_lvl_monitors(const struct sff_diags * sd)676*1b481fc3SMaciej Żenczykowski static void cmis_show_dom_mod_lvl_monitors(const struct sff_diags *sd)
677*1b481fc3SMaciej Żenczykowski {
678*1b481fc3SMaciej Żenczykowski 	PRINT_TEMP("Module temperature", sd->sfp_temp[MCURR]);
679*1b481fc3SMaciej Żenczykowski 	PRINT_VCC("Module voltage", sd->sfp_voltage[MCURR]);
680*1b481fc3SMaciej Żenczykowski }
681*1b481fc3SMaciej Żenczykowski 
682*1b481fc3SMaciej Żenczykowski /* Print channel Tx laser bias current. Relevant documents:
683*1b481fc3SMaciej Żenczykowski  * [1] CMIS Rev. 5, page 165, section 8.9.4, Table 8-79
684*1b481fc3SMaciej Żenczykowski  */
685*1b481fc3SMaciej Żenczykowski static void
cmis_show_dom_chan_lvl_tx_bias_bank(const struct cmis_memory_map * map,const struct sff_diags * sd,int bank)686*1b481fc3SMaciej Żenczykowski cmis_show_dom_chan_lvl_tx_bias_bank(const struct cmis_memory_map *map,
687*1b481fc3SMaciej Żenczykowski 				    const struct sff_diags *sd, int bank)
688*1b481fc3SMaciej Żenczykowski {
689*1b481fc3SMaciej Żenczykowski 	const __u8 *page_11h = map->upper_memory[bank][0x11];
690*1b481fc3SMaciej Żenczykowski 	int i;
691*1b481fc3SMaciej Żenczykowski 
692*1b481fc3SMaciej Żenczykowski 	if (!page_11h)
693*1b481fc3SMaciej Żenczykowski 		return;
694*1b481fc3SMaciej Żenczykowski 
695*1b481fc3SMaciej Żenczykowski 	for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) {
696*1b481fc3SMaciej Żenczykowski 		int chan = bank * CMIS_CHANNELS_PER_BANK + i;
697*1b481fc3SMaciej Żenczykowski 		char fmt_str[80];
698*1b481fc3SMaciej Żenczykowski 
699*1b481fc3SMaciej Żenczykowski 		snprintf(fmt_str, 80, "%s (Channel %d)",
700*1b481fc3SMaciej Żenczykowski 			 "Laser tx bias current", chan + 1);
701*1b481fc3SMaciej Żenczykowski 		PRINT_BIAS(fmt_str, sd->scd[chan].bias_cur);
702*1b481fc3SMaciej Żenczykowski 	}
703*1b481fc3SMaciej Żenczykowski }
704*1b481fc3SMaciej Żenczykowski 
cmis_show_dom_chan_lvl_tx_bias(const struct cmis_memory_map * map,const struct sff_diags * sd)705*1b481fc3SMaciej Żenczykowski static void cmis_show_dom_chan_lvl_tx_bias(const struct cmis_memory_map *map,
706*1b481fc3SMaciej Żenczykowski 					   const struct sff_diags *sd)
707*1b481fc3SMaciej Żenczykowski {
708*1b481fc3SMaciej Żenczykowski 	int i;
709*1b481fc3SMaciej Żenczykowski 
710*1b481fc3SMaciej Żenczykowski 	if(!(map->page_01h[CMIS_DIAG_CHAN_ADVER_OFFSET] &
711*1b481fc3SMaciej Żenczykowski 	     CMIS_TX_BIAS_MON_MASK))
712*1b481fc3SMaciej Żenczykowski 		return;
713*1b481fc3SMaciej Żenczykowski 
714*1b481fc3SMaciej Żenczykowski 	for (i = 0; i < CMIS_MAX_BANKS; i++)
715*1b481fc3SMaciej Żenczykowski 		cmis_show_dom_chan_lvl_tx_bias_bank(map, sd, i);
716*1b481fc3SMaciej Żenczykowski }
717*1b481fc3SMaciej Żenczykowski 
718*1b481fc3SMaciej Żenczykowski /* Print channel Tx average optical power. Relevant documents:
719*1b481fc3SMaciej Żenczykowski  * [1] CMIS Rev. 5, page 165, section 8.9.4, Table 8-79
720*1b481fc3SMaciej Żenczykowski  */
721*1b481fc3SMaciej Żenczykowski static void
cmis_show_dom_chan_lvl_tx_power_bank(const struct cmis_memory_map * map,const struct sff_diags * sd,int bank)722*1b481fc3SMaciej Żenczykowski cmis_show_dom_chan_lvl_tx_power_bank(const struct cmis_memory_map *map,
723*1b481fc3SMaciej Żenczykowski 				     const struct sff_diags *sd, int bank)
724*1b481fc3SMaciej Żenczykowski {
725*1b481fc3SMaciej Żenczykowski 	const __u8 *page_11h = map->upper_memory[bank][0x11];
726*1b481fc3SMaciej Żenczykowski 	int i;
727*1b481fc3SMaciej Żenczykowski 
728*1b481fc3SMaciej Żenczykowski 	if (!page_11h)
729*1b481fc3SMaciej Żenczykowski 		return;
730*1b481fc3SMaciej Żenczykowski 
731*1b481fc3SMaciej Żenczykowski 	for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) {
732*1b481fc3SMaciej Żenczykowski 		int chan = bank * CMIS_CHANNELS_PER_BANK + i;
733*1b481fc3SMaciej Żenczykowski 		char fmt_str[80];
734*1b481fc3SMaciej Żenczykowski 
735*1b481fc3SMaciej Żenczykowski 		snprintf(fmt_str, 80, "%s (Channel %d)",
736*1b481fc3SMaciej Żenczykowski 			 "Transmit avg optical power", chan + 1);
737*1b481fc3SMaciej Żenczykowski 		PRINT_xX_PWR(fmt_str, sd->scd[chan].tx_power);
738*1b481fc3SMaciej Żenczykowski 	}
739*1b481fc3SMaciej Żenczykowski }
740*1b481fc3SMaciej Żenczykowski 
cmis_show_dom_chan_lvl_tx_power(const struct cmis_memory_map * map,const struct sff_diags * sd)741*1b481fc3SMaciej Żenczykowski static void cmis_show_dom_chan_lvl_tx_power(const struct cmis_memory_map *map,
742*1b481fc3SMaciej Żenczykowski 					    const struct sff_diags *sd)
743*1b481fc3SMaciej Żenczykowski {
744*1b481fc3SMaciej Żenczykowski 	int i;
745*1b481fc3SMaciej Żenczykowski 
746*1b481fc3SMaciej Żenczykowski 	if (!sd->tx_power_type)
747*1b481fc3SMaciej Żenczykowski 		return;
748*1b481fc3SMaciej Żenczykowski 
749*1b481fc3SMaciej Żenczykowski 	for (i = 0; i < CMIS_MAX_BANKS; i++)
750*1b481fc3SMaciej Żenczykowski 		cmis_show_dom_chan_lvl_tx_power_bank(map, sd, i);
751*1b481fc3SMaciej Żenczykowski }
752*1b481fc3SMaciej Żenczykowski 
753*1b481fc3SMaciej Żenczykowski /* Print channel Rx input optical power. Relevant documents:
754*1b481fc3SMaciej Żenczykowski  * [1] CMIS Rev. 5, page 165, section 8.9.4, Table 8-79
755*1b481fc3SMaciej Żenczykowski  */
756*1b481fc3SMaciej Żenczykowski static void
cmis_show_dom_chan_lvl_rx_power_bank(const struct cmis_memory_map * map,const struct sff_diags * sd,int bank)757*1b481fc3SMaciej Żenczykowski cmis_show_dom_chan_lvl_rx_power_bank(const struct cmis_memory_map *map,
758*1b481fc3SMaciej Żenczykowski 				     const struct sff_diags *sd, int bank)
759*1b481fc3SMaciej Żenczykowski {
760*1b481fc3SMaciej Żenczykowski 	const __u8 *page_11h = map->upper_memory[bank][0x11];
761*1b481fc3SMaciej Żenczykowski 	int i;
762*1b481fc3SMaciej Żenczykowski 
763*1b481fc3SMaciej Żenczykowski 	if (!page_11h)
764*1b481fc3SMaciej Żenczykowski 		return;
765*1b481fc3SMaciej Żenczykowski 
766*1b481fc3SMaciej Żenczykowski 	for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) {
767*1b481fc3SMaciej Żenczykowski 		int chan = bank * CMIS_CHANNELS_PER_BANK + i;
768*1b481fc3SMaciej Żenczykowski 		char *rx_power_str;
769*1b481fc3SMaciej Żenczykowski 		char fmt_str[80];
770*1b481fc3SMaciej Żenczykowski 
771*1b481fc3SMaciej Żenczykowski 		if (!sd->rx_power_type)
772*1b481fc3SMaciej Żenczykowski 			rx_power_str = "Receiver signal OMA";
773*1b481fc3SMaciej Żenczykowski 		else
774*1b481fc3SMaciej Żenczykowski 			rx_power_str = "Rcvr signal avg optical power";
775*1b481fc3SMaciej Żenczykowski 
776*1b481fc3SMaciej Żenczykowski 		snprintf(fmt_str, 80, "%s (Channel %d)", rx_power_str,
777*1b481fc3SMaciej Żenczykowski 			 chan + 1);
778*1b481fc3SMaciej Żenczykowski 		PRINT_xX_PWR(fmt_str, sd->scd[chan].rx_power);
779*1b481fc3SMaciej Żenczykowski 	}
780*1b481fc3SMaciej Żenczykowski }
781*1b481fc3SMaciej Żenczykowski 
cmis_show_dom_chan_lvl_rx_power(const struct cmis_memory_map * map,const struct sff_diags * sd)782*1b481fc3SMaciej Żenczykowski static void cmis_show_dom_chan_lvl_rx_power(const struct cmis_memory_map *map,
783*1b481fc3SMaciej Żenczykowski 					    const struct sff_diags *sd)
784*1b481fc3SMaciej Żenczykowski {
785*1b481fc3SMaciej Żenczykowski 	int i;
786*1b481fc3SMaciej Żenczykowski 
787*1b481fc3SMaciej Żenczykowski 	if(!(map->page_01h[CMIS_DIAG_CHAN_ADVER_OFFSET] & CMIS_RX_PWR_MON_MASK))
788*1b481fc3SMaciej Żenczykowski 		return;
789*1b481fc3SMaciej Żenczykowski 
790*1b481fc3SMaciej Żenczykowski 	for (i = 0; i < CMIS_MAX_BANKS; i++)
791*1b481fc3SMaciej Żenczykowski 		cmis_show_dom_chan_lvl_rx_power_bank(map, sd, i);
792*1b481fc3SMaciej Żenczykowski }
793*1b481fc3SMaciej Żenczykowski 
cmis_show_dom_chan_lvl_monitors(const struct cmis_memory_map * map,const struct sff_diags * sd)794*1b481fc3SMaciej Żenczykowski static void cmis_show_dom_chan_lvl_monitors(const struct cmis_memory_map *map,
795*1b481fc3SMaciej Żenczykowski 					    const struct sff_diags *sd)
796*1b481fc3SMaciej Żenczykowski {
797*1b481fc3SMaciej Żenczykowski 	cmis_show_dom_chan_lvl_tx_bias(map, sd);
798*1b481fc3SMaciej Żenczykowski 	cmis_show_dom_chan_lvl_tx_power(map, sd);
799*1b481fc3SMaciej Żenczykowski 	cmis_show_dom_chan_lvl_rx_power(map, sd);
800*1b481fc3SMaciej Żenczykowski }
801*1b481fc3SMaciej Żenczykowski 
802*1b481fc3SMaciej Żenczykowski /* Print module-level flags. Relevant documents:
803*1b481fc3SMaciej Żenczykowski  * [1] CMIS Rev. 5, page 109, section 8.2.4, Table 8-8
804*1b481fc3SMaciej Żenczykowski  */
cmis_show_dom_mod_lvl_flags(const struct cmis_memory_map * map)805*1b481fc3SMaciej Żenczykowski static void cmis_show_dom_mod_lvl_flags(const struct cmis_memory_map *map)
806*1b481fc3SMaciej Żenczykowski {
807*1b481fc3SMaciej Żenczykowski 	int i;
808*1b481fc3SMaciej Żenczykowski 
809*1b481fc3SMaciej Żenczykowski 	for (i = 0; cmis_aw_mod_flags[i].str; i++) {
810*1b481fc3SMaciej Żenczykowski 		printf("\t%-41s : %s\n", cmis_aw_mod_flags[i].str,
811*1b481fc3SMaciej Żenczykowski 		       map->lower_memory[cmis_aw_mod_flags[i].offset] &
812*1b481fc3SMaciej Żenczykowski 		       cmis_aw_mod_flags[i].value ? "On" : "Off");
813*1b481fc3SMaciej Żenczykowski 	}
814*1b481fc3SMaciej Żenczykowski }
815*1b481fc3SMaciej Żenczykowski 
816*1b481fc3SMaciej Żenczykowski /* Print channel-level flags. Relevant documents:
817*1b481fc3SMaciej Żenczykowski  * [1] CMIS Rev. 5, page 162, section 8.9.3, Table 8-77
818*1b481fc3SMaciej Żenczykowski  * [1] CMIS Rev. 5, page 164, section 8.9.3, Table 8-78
819*1b481fc3SMaciej Żenczykowski  */
cmis_show_dom_chan_lvl_flags_chan(const struct cmis_memory_map * map,int bank,int chan)820*1b481fc3SMaciej Żenczykowski static void cmis_show_dom_chan_lvl_flags_chan(const struct cmis_memory_map *map,
821*1b481fc3SMaciej Żenczykowski 					      int bank, int chan)
822*1b481fc3SMaciej Żenczykowski {
823*1b481fc3SMaciej Żenczykowski 	const __u8 *page_11h = map->upper_memory[bank][0x11];
824*1b481fc3SMaciej Żenczykowski 	int i;
825*1b481fc3SMaciej Żenczykowski 
826*1b481fc3SMaciej Żenczykowski 	for (i = 0; cmis_aw_chan_flags[i].fmt_str; i++) {
827*1b481fc3SMaciej Żenczykowski 		char str[80];
828*1b481fc3SMaciej Żenczykowski 
829*1b481fc3SMaciej Żenczykowski 		if (!(map->page_01h[cmis_aw_chan_flags[i].adver_offset] &
830*1b481fc3SMaciej Żenczykowski 		      cmis_aw_chan_flags[i].adver_value))
831*1b481fc3SMaciej Żenczykowski 			continue;
832*1b481fc3SMaciej Żenczykowski 
833*1b481fc3SMaciej Żenczykowski 		snprintf(str, 80, cmis_aw_chan_flags[i].fmt_str, chan + 1);
834*1b481fc3SMaciej Żenczykowski 		printf("\t%-41s : %s\n", str,
835*1b481fc3SMaciej Żenczykowski 		       page_11h[cmis_aw_chan_flags[i].offset] & chan ?
836*1b481fc3SMaciej Żenczykowski 		       "On" : "Off");
837*1b481fc3SMaciej Żenczykowski 	}
838*1b481fc3SMaciej Żenczykowski }
839*1b481fc3SMaciej Żenczykowski 
840*1b481fc3SMaciej Żenczykowski static void
cmis_show_dom_chan_lvl_flags_bank(const struct cmis_memory_map * map,int bank)841*1b481fc3SMaciej Żenczykowski cmis_show_dom_chan_lvl_flags_bank(const struct cmis_memory_map *map,
842*1b481fc3SMaciej Żenczykowski 				  int bank)
843*1b481fc3SMaciej Żenczykowski {
844*1b481fc3SMaciej Żenczykowski 	const __u8 *page_11h = map->upper_memory[bank][0x11];
845*1b481fc3SMaciej Żenczykowski 	int i;
846*1b481fc3SMaciej Żenczykowski 
847*1b481fc3SMaciej Żenczykowski 	if (!page_11h)
848*1b481fc3SMaciej Żenczykowski 		return;
849*1b481fc3SMaciej Żenczykowski 
850*1b481fc3SMaciej Żenczykowski 	for (i = 0; i < CMIS_CHANNELS_PER_BANK; i++) {
851*1b481fc3SMaciej Żenczykowski 		int chan = bank * CMIS_CHANNELS_PER_BANK + i;
852*1b481fc3SMaciej Żenczykowski 
853*1b481fc3SMaciej Żenczykowski 		cmis_show_dom_chan_lvl_flags_chan(map, bank, chan);
854*1b481fc3SMaciej Żenczykowski 	}
855*1b481fc3SMaciej Żenczykowski }
856*1b481fc3SMaciej Żenczykowski 
cmis_show_dom_chan_lvl_flags(const struct cmis_memory_map * map)857*1b481fc3SMaciej Żenczykowski static void cmis_show_dom_chan_lvl_flags(const struct cmis_memory_map *map)
858*1b481fc3SMaciej Żenczykowski {
859*1b481fc3SMaciej Żenczykowski 	int i;
860*1b481fc3SMaciej Żenczykowski 
861*1b481fc3SMaciej Żenczykowski 	for (i = 0; i < CMIS_MAX_BANKS; i++)
862*1b481fc3SMaciej Żenczykowski 		cmis_show_dom_chan_lvl_flags_bank(map, i);
863*1b481fc3SMaciej Żenczykowski }
864*1b481fc3SMaciej Żenczykowski 
865*1b481fc3SMaciej Żenczykowski 
cmis_show_dom(const struct cmis_memory_map * map)866*1b481fc3SMaciej Żenczykowski static void cmis_show_dom(const struct cmis_memory_map *map)
867*1b481fc3SMaciej Żenczykowski {
868*1b481fc3SMaciej Żenczykowski 	struct sff_diags sd = {};
869*1b481fc3SMaciej Żenczykowski 
870*1b481fc3SMaciej Żenczykowski 	/* Diagnostic information is only relevant when the module memory
871*1b481fc3SMaciej Żenczykowski 	 * model is paged and not flat.
872*1b481fc3SMaciej Żenczykowski 	 */
873*1b481fc3SMaciej Żenczykowski 	if (map->lower_memory[CMIS_MEMORY_MODEL_OFFSET] &
874*1b481fc3SMaciej Żenczykowski 	    CMIS_MEMORY_MODEL_MASK)
875*1b481fc3SMaciej Żenczykowski 		return;
876*1b481fc3SMaciej Żenczykowski 
877*1b481fc3SMaciej Żenczykowski 	cmis_parse_dom(map, &sd);
878*1b481fc3SMaciej Żenczykowski 
879*1b481fc3SMaciej Żenczykowski 	cmis_show_dom_mod_lvl_monitors(&sd);
880*1b481fc3SMaciej Żenczykowski 	cmis_show_dom_chan_lvl_monitors(map, &sd);
881*1b481fc3SMaciej Żenczykowski 	cmis_show_dom_mod_lvl_flags(map);
882*1b481fc3SMaciej Żenczykowski 	cmis_show_dom_chan_lvl_flags(map);
883*1b481fc3SMaciej Żenczykowski 	if (sd.supports_alarms)
884*1b481fc3SMaciej Żenczykowski 		sff_show_thresholds(sd);
885*1b481fc3SMaciej Żenczykowski }
886*1b481fc3SMaciej Żenczykowski 
cmis_show_all_common(const struct cmis_memory_map * map)887*1b481fc3SMaciej Żenczykowski static void cmis_show_all_common(const struct cmis_memory_map *map)
888*1b481fc3SMaciej Żenczykowski {
889*1b481fc3SMaciej Żenczykowski 	cmis_show_identifier(map);
890*1b481fc3SMaciej Żenczykowski 	cmis_show_power_info(map);
891*1b481fc3SMaciej Żenczykowski 	cmis_show_connector(map);
892*1b481fc3SMaciej Żenczykowski 	cmis_show_cbl_asm_len(map);
893*1b481fc3SMaciej Żenczykowski 	cmis_show_sig_integrity(map);
894*1b481fc3SMaciej Żenczykowski 	cmis_show_mit_compliance(map);
895*1b481fc3SMaciej Żenczykowski 	cmis_show_link_len(map);
896*1b481fc3SMaciej Żenczykowski 	cmis_show_vendor_info(map);
897*1b481fc3SMaciej Żenczykowski 	cmis_show_rev_compliance(map);
898*1b481fc3SMaciej Żenczykowski 	cmis_show_signals(map);
899*1b481fc3SMaciej Żenczykowski 	cmis_show_mod_state(map);
900*1b481fc3SMaciej Żenczykowski 	cmis_show_mod_fault_cause(map);
901*1b481fc3SMaciej Żenczykowski 	cmis_show_mod_lvl_controls(map);
902*1b481fc3SMaciej Żenczykowski 	cmis_show_dom(map);
903*1b481fc3SMaciej Żenczykowski }
904*1b481fc3SMaciej Żenczykowski 
cmis_memory_map_init_buf(struct cmis_memory_map * map,const __u8 * id)905*1b481fc3SMaciej Żenczykowski static void cmis_memory_map_init_buf(struct cmis_memory_map *map,
906*1b481fc3SMaciej Żenczykowski 				     const __u8 *id)
907*1b481fc3SMaciej Żenczykowski {
908*1b481fc3SMaciej Żenczykowski 	/* Lower Memory and Page 00h are always present.
909*1b481fc3SMaciej Żenczykowski 	 *
910*1b481fc3SMaciej Żenczykowski 	 * Offset into Upper Memory is between page size and twice the page
911*1b481fc3SMaciej Żenczykowski 	 * size. Therefore, set the base address of each page to base address
912*1b481fc3SMaciej Żenczykowski 	 * plus page size multiplied by the page number.
913*1b481fc3SMaciej Żenczykowski 	 */
914*1b481fc3SMaciej Żenczykowski 	map->lower_memory = id;
915*1b481fc3SMaciej Żenczykowski 	map->page_00h = id;
916*1b481fc3SMaciej Żenczykowski 
917*1b481fc3SMaciej Żenczykowski 	/* Page 01h is only present when the module memory model is paged and
918*1b481fc3SMaciej Żenczykowski 	 * not flat.
919*1b481fc3SMaciej Żenczykowski 	 */
920*1b481fc3SMaciej Żenczykowski 	if (map->lower_memory[CMIS_MEMORY_MODEL_OFFSET] &
921*1b481fc3SMaciej Żenczykowski 	    CMIS_MEMORY_MODEL_MASK)
922*1b481fc3SMaciej Żenczykowski 		return;
923*1b481fc3SMaciej Żenczykowski 
924*1b481fc3SMaciej Żenczykowski 	map->page_01h = id + CMIS_PAGE_SIZE;
925*1b481fc3SMaciej Żenczykowski }
926*1b481fc3SMaciej Żenczykowski 
cmis_show_all_ioctl(const __u8 * id)927*1b481fc3SMaciej Żenczykowski void cmis_show_all_ioctl(const __u8 *id)
928*1b481fc3SMaciej Żenczykowski {
929*1b481fc3SMaciej Żenczykowski 	struct cmis_memory_map map = {};
930*1b481fc3SMaciej Żenczykowski 
931*1b481fc3SMaciej Żenczykowski 	cmis_memory_map_init_buf(&map, id);
932*1b481fc3SMaciej Żenczykowski 	cmis_show_all_common(&map);
933*1b481fc3SMaciej Żenczykowski }
934*1b481fc3SMaciej Żenczykowski 
cmis_request_init(struct ethtool_module_eeprom * request,u8 bank,u8 page,u32 offset)935*1b481fc3SMaciej Żenczykowski static void cmis_request_init(struct ethtool_module_eeprom *request, u8 bank,
936*1b481fc3SMaciej Żenczykowski 			      u8 page, u32 offset)
937*1b481fc3SMaciej Żenczykowski {
938*1b481fc3SMaciej Żenczykowski 	request->offset = offset;
939*1b481fc3SMaciej Żenczykowski 	request->length = CMIS_PAGE_SIZE;
940*1b481fc3SMaciej Żenczykowski 	request->page = page;
941*1b481fc3SMaciej Żenczykowski 	request->bank = bank;
942*1b481fc3SMaciej Żenczykowski 	request->i2c_address = CMIS_I2C_ADDRESS;
943*1b481fc3SMaciej Żenczykowski 	request->data = NULL;
944*1b481fc3SMaciej Żenczykowski }
945*1b481fc3SMaciej Żenczykowski 
cmis_num_banks_get(const struct cmis_memory_map * map,int * p_num_banks)946*1b481fc3SMaciej Żenczykowski static int cmis_num_banks_get(const struct cmis_memory_map *map,
947*1b481fc3SMaciej Żenczykowski 			      int *p_num_banks)
948*1b481fc3SMaciej Żenczykowski {
949*1b481fc3SMaciej Żenczykowski 	switch (map->page_01h[CMIS_PAGES_ADVER_OFFSET] &
950*1b481fc3SMaciej Żenczykowski 		CMIS_BANKS_SUPPORTED_MASK) {
951*1b481fc3SMaciej Żenczykowski 	case CMIS_BANK_0_SUPPORTED:
952*1b481fc3SMaciej Żenczykowski 		*p_num_banks = 1;
953*1b481fc3SMaciej Żenczykowski 		break;
954*1b481fc3SMaciej Żenczykowski 	case CMIS_BANK_0_1_SUPPORTED:
955*1b481fc3SMaciej Żenczykowski 		*p_num_banks = 2;
956*1b481fc3SMaciej Żenczykowski 		break;
957*1b481fc3SMaciej Żenczykowski 	case CMIS_BANK_0_3_SUPPORTED:
958*1b481fc3SMaciej Żenczykowski 		*p_num_banks = 4;
959*1b481fc3SMaciej Żenczykowski 		break;
960*1b481fc3SMaciej Żenczykowski 	default:
961*1b481fc3SMaciej Żenczykowski 		return -EINVAL;
962*1b481fc3SMaciej Żenczykowski 	}
963*1b481fc3SMaciej Żenczykowski 
964*1b481fc3SMaciej Żenczykowski 	return 0;
965*1b481fc3SMaciej Żenczykowski }
966*1b481fc3SMaciej Żenczykowski 
967*1b481fc3SMaciej Żenczykowski static int
cmis_memory_map_init_pages(struct cmd_context * ctx,struct cmis_memory_map * map)968*1b481fc3SMaciej Żenczykowski cmis_memory_map_init_pages(struct cmd_context *ctx,
969*1b481fc3SMaciej Żenczykowski 			   struct cmis_memory_map *map)
970*1b481fc3SMaciej Żenczykowski {
971*1b481fc3SMaciej Żenczykowski 	struct ethtool_module_eeprom request;
972*1b481fc3SMaciej Żenczykowski 	int num_banks, i, ret;
973*1b481fc3SMaciej Żenczykowski 
974*1b481fc3SMaciej Żenczykowski 	/* Lower Memory and Page 00h are always present.
975*1b481fc3SMaciej Żenczykowski 	 *
976*1b481fc3SMaciej Żenczykowski 	 * Offset into Upper Memory is between page size and twice the page
977*1b481fc3SMaciej Żenczykowski 	 * size. Therefore, set the base address of each page to its base
978*1b481fc3SMaciej Żenczykowski 	 * address minus page size.
979*1b481fc3SMaciej Żenczykowski 	 */
980*1b481fc3SMaciej Żenczykowski 	cmis_request_init(&request, 0, 0x0, 0);
981*1b481fc3SMaciej Żenczykowski 	ret = nl_get_eeprom_page(ctx, &request);
982*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
983*1b481fc3SMaciej Żenczykowski 		return ret;
984*1b481fc3SMaciej Żenczykowski 	map->lower_memory = request.data;
985*1b481fc3SMaciej Żenczykowski 
986*1b481fc3SMaciej Żenczykowski 	cmis_request_init(&request, 0, 0x0, CMIS_PAGE_SIZE);
987*1b481fc3SMaciej Żenczykowski 	ret = nl_get_eeprom_page(ctx, &request);
988*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
989*1b481fc3SMaciej Żenczykowski 		return ret;
990*1b481fc3SMaciej Żenczykowski 	map->page_00h = request.data - CMIS_PAGE_SIZE;
991*1b481fc3SMaciej Żenczykowski 
992*1b481fc3SMaciej Żenczykowski 	/* Pages 01h and 02h are only present when the module memory model is
993*1b481fc3SMaciej Żenczykowski 	 * paged and not flat.
994*1b481fc3SMaciej Żenczykowski 	 */
995*1b481fc3SMaciej Żenczykowski 	if (map->lower_memory[CMIS_MEMORY_MODEL_OFFSET] &
996*1b481fc3SMaciej Żenczykowski 	    CMIS_MEMORY_MODEL_MASK)
997*1b481fc3SMaciej Żenczykowski 		return 0;
998*1b481fc3SMaciej Żenczykowski 
999*1b481fc3SMaciej Żenczykowski 	cmis_request_init(&request, 0, 0x1, CMIS_PAGE_SIZE);
1000*1b481fc3SMaciej Żenczykowski 	ret = nl_get_eeprom_page(ctx, &request);
1001*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
1002*1b481fc3SMaciej Żenczykowski 		return ret;
1003*1b481fc3SMaciej Żenczykowski 	map->page_01h = request.data - CMIS_PAGE_SIZE;
1004*1b481fc3SMaciej Żenczykowski 
1005*1b481fc3SMaciej Żenczykowski 	cmis_request_init(&request, 0, 0x2, CMIS_PAGE_SIZE);
1006*1b481fc3SMaciej Żenczykowski 	ret = nl_get_eeprom_page(ctx, &request);
1007*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
1008*1b481fc3SMaciej Żenczykowski 		return ret;
1009*1b481fc3SMaciej Żenczykowski 	map->page_02h = request.data - CMIS_PAGE_SIZE;
1010*1b481fc3SMaciej Żenczykowski 
1011*1b481fc3SMaciej Żenczykowski 	/* Bank 0 of Page 11h provides lane-specific registers for the first 8
1012*1b481fc3SMaciej Żenczykowski 	 * lanes, and each additional Banks provides support for an additional
1013*1b481fc3SMaciej Żenczykowski 	 * 8 lanes. Only initialize supported Banks.
1014*1b481fc3SMaciej Żenczykowski 	 */
1015*1b481fc3SMaciej Żenczykowski 	ret = cmis_num_banks_get(map, &num_banks);
1016*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
1017*1b481fc3SMaciej Żenczykowski 		return ret;
1018*1b481fc3SMaciej Żenczykowski 
1019*1b481fc3SMaciej Żenczykowski 	for (i = 0; i < num_banks; i++) {
1020*1b481fc3SMaciej Żenczykowski 		cmis_request_init(&request, i, 0x11, CMIS_PAGE_SIZE);
1021*1b481fc3SMaciej Żenczykowski 		ret = nl_get_eeprom_page(ctx, &request);
1022*1b481fc3SMaciej Żenczykowski 		if (ret < 0)
1023*1b481fc3SMaciej Żenczykowski 			return ret;
1024*1b481fc3SMaciej Żenczykowski 		map->upper_memory[i][0x11] = request.data - CMIS_PAGE_SIZE;
1025*1b481fc3SMaciej Żenczykowski 	}
1026*1b481fc3SMaciej Żenczykowski 
1027*1b481fc3SMaciej Żenczykowski 	return 0;
1028*1b481fc3SMaciej Żenczykowski }
1029*1b481fc3SMaciej Żenczykowski 
cmis_show_all_nl(struct cmd_context * ctx)1030*1b481fc3SMaciej Żenczykowski int cmis_show_all_nl(struct cmd_context *ctx)
1031*1b481fc3SMaciej Żenczykowski {
1032*1b481fc3SMaciej Żenczykowski 	struct cmis_memory_map map = {};
1033*1b481fc3SMaciej Żenczykowski 	int ret;
1034*1b481fc3SMaciej Żenczykowski 
1035*1b481fc3SMaciej Żenczykowski 	ret = cmis_memory_map_init_pages(ctx, &map);
1036*1b481fc3SMaciej Żenczykowski 	if (ret < 0)
1037*1b481fc3SMaciej Żenczykowski 		return ret;
1038*1b481fc3SMaciej Żenczykowski 	cmis_show_all_common(&map);
1039*1b481fc3SMaciej Żenczykowski 
1040*1b481fc3SMaciej Żenczykowski 	return 0;
1041*1b481fc3SMaciej Żenczykowski }
1042