ethernet: add sanity checks to p2p_ethernet_add/del
[vpp.git] / src / vnet / ethernet / sfp.c
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <vnet/ethernet/sfp.h>
17
18 static u8 *
19 format_space_terminated (u8 * s, va_list * args)
20 {
21   u32 l = va_arg (*args, u32);
22   u8 *v = va_arg (*args, u8 *);
23   u8 *p;
24
25   for (p = v + l - 1; p >= v && p[0] == ' '; p--)
26     ;
27   vec_add (s, v, clib_min (p - v + 1, l));
28   return s;
29 }
30
31 static u8 *
32 format_sfp_id (u8 * s, va_list * args)
33 {
34   u32 id = va_arg (*args, u32);
35   char *t = 0;
36   switch (id)
37     {
38 #define _(f,str) case SFP_ID_##f: t = str; break;
39       foreach_sfp_id
40 #undef _
41     default:
42       return format (s, "unknown 0x%x", id);
43     }
44   return format (s, "%s", t);
45 }
46
47 static u8 *
48 format_sfp_compatibility (u8 * s, va_list * args)
49 {
50   u32 c = va_arg (*args, u32);
51   char *t = 0;
52   switch (c)
53     {
54 #define _(a,b,f) case SFP_COMPATIBILITY_##f: t = #f; break;
55       foreach_sfp_compatibility
56 #undef _
57     default:
58       return format (s, "unknown 0x%x", c);
59     }
60   return format (s, "%s", t);
61 }
62
63 u32
64 sfp_is_comatible (sfp_eeprom_t * e, sfp_compatibility_t c)
65 {
66   static struct
67   {
68     u8 byte, bit;
69   } t[] =
70   {
71 #define _(a,b,f) { .byte = a, .bit = b, },
72     foreach_sfp_compatibility
73 #undef _
74   };
75
76   ASSERT (c < ARRAY_LEN (t));
77   return (e->compatibility[t[c].byte] & (1 << t[c].bit)) != 0;
78 }
79
80 u8 *
81 format_sfp_eeprom (u8 * s, va_list * args)
82 {
83   sfp_eeprom_t *e = va_arg (*args, sfp_eeprom_t *);
84   u32 indent = format_get_indent (s);
85   int i;
86
87   s = format (s, "id %U, ", format_sfp_id, e->id);
88
89   s = format (s, "compatibility:");
90   for (i = 0; i < SFP_N_COMPATIBILITY; i++)
91     if (sfp_is_comatible (e, i))
92       s = format (s, " %U", format_sfp_compatibility, i);
93
94   s = format (s, "\n%Uvendor: %U, part %U",
95               format_white_space, indent,
96               format_space_terminated, sizeof (e->vendor_name),
97               e->vendor_name, format_space_terminated,
98               sizeof (e->vendor_part_number), e->vendor_part_number);
99   s =
100     format (s, "\n%Urevision: %U, serial: %U, date code: %U",
101             format_white_space, indent, format_space_terminated,
102             sizeof (e->vendor_revision), e->vendor_revision,
103             format_space_terminated, sizeof (e->vendor_serial_number),
104             e->vendor_serial_number, format_space_terminated,
105             sizeof (e->vendor_date_code), e->vendor_date_code);
106
107   if (e->length[4])
108     s = format (s, "\n%Ucable length: %um", format_white_space, indent,
109                 e->length[4]);
110
111   return s;
112 }
113
114 /*
115  * fd.io coding-style-patch-verification: ON
116  *
117  * Local Variables:
118  * eval: (c-set-style "gnu")
119  * End:
120  */