thunderbolt: Read port configuration from eeprom.
[firefly-linux-kernel-4.4.55.git] / drivers / thunderbolt / eeprom.c
1 /*
2  * Thunderbolt Cactus Ridge driver - eeprom access
3  *
4  * Copyright (c) 2014 Andreas Noever <andreas.noever@gmail.com>
5  */
6
7 #include <linux/crc32.h>
8 #include "tb.h"
9
10 /**
11  * tb_eeprom_ctl_write() - write control word
12  */
13 static int tb_eeprom_ctl_write(struct tb_switch *sw, struct tb_eeprom_ctl *ctl)
14 {
15         return tb_sw_write(sw, ctl, TB_CFG_SWITCH, sw->cap_plug_events + 4, 1);
16 }
17
18 /**
19  * tb_eeprom_ctl_write() - read control word
20  */
21 static int tb_eeprom_ctl_read(struct tb_switch *sw, struct tb_eeprom_ctl *ctl)
22 {
23         return tb_sw_read(sw, ctl, TB_CFG_SWITCH, sw->cap_plug_events + 4, 1);
24 }
25
26 enum tb_eeprom_transfer {
27         TB_EEPROM_IN,
28         TB_EEPROM_OUT,
29 };
30
31 /**
32  * tb_eeprom_active - enable rom access
33  *
34  * WARNING: Always disable access after usage. Otherwise the controller will
35  * fail to reprobe.
36  */
37 static int tb_eeprom_active(struct tb_switch *sw, bool enable)
38 {
39         struct tb_eeprom_ctl ctl;
40         int res = tb_eeprom_ctl_read(sw, &ctl);
41         if (res)
42                 return res;
43         if (enable) {
44                 ctl.access_high = 1;
45                 res = tb_eeprom_ctl_write(sw, &ctl);
46                 if (res)
47                         return res;
48                 ctl.access_low = 0;
49                 return tb_eeprom_ctl_write(sw, &ctl);
50         } else {
51                 ctl.access_low = 1;
52                 res = tb_eeprom_ctl_write(sw, &ctl);
53                 if (res)
54                         return res;
55                 ctl.access_high = 0;
56                 return tb_eeprom_ctl_write(sw, &ctl);
57         }
58 }
59
60 /**
61  * tb_eeprom_transfer - transfer one bit
62  *
63  * If TB_EEPROM_IN is passed, then the bit can be retrieved from ctl->data_in.
64  * If TB_EEPROM_OUT is passed, then ctl->data_out will be written.
65  */
66 static int tb_eeprom_transfer(struct tb_switch *sw, struct tb_eeprom_ctl *ctl,
67                               enum tb_eeprom_transfer direction)
68 {
69         int res;
70         if (direction == TB_EEPROM_OUT) {
71                 res = tb_eeprom_ctl_write(sw, ctl);
72                 if (res)
73                         return res;
74         }
75         ctl->clock = 1;
76         res = tb_eeprom_ctl_write(sw, ctl);
77         if (res)
78                 return res;
79         if (direction == TB_EEPROM_IN) {
80                 res = tb_eeprom_ctl_read(sw, ctl);
81                 if (res)
82                         return res;
83         }
84         ctl->clock = 0;
85         return tb_eeprom_ctl_write(sw, ctl);
86 }
87
88 /**
89  * tb_eeprom_out - write one byte to the bus
90  */
91 static int tb_eeprom_out(struct tb_switch *sw, u8 val)
92 {
93         struct tb_eeprom_ctl ctl;
94         int i;
95         int res = tb_eeprom_ctl_read(sw, &ctl);
96         if (res)
97                 return res;
98         for (i = 0; i < 8; i++) {
99                 ctl.data_out = val & 0x80;
100                 res = tb_eeprom_transfer(sw, &ctl, TB_EEPROM_OUT);
101                 if (res)
102                         return res;
103                 val <<= 1;
104         }
105         return 0;
106 }
107
108 /**
109  * tb_eeprom_in - read one byte from the bus
110  */
111 static int tb_eeprom_in(struct tb_switch *sw, u8 *val)
112 {
113         struct tb_eeprom_ctl ctl;
114         int i;
115         int res = tb_eeprom_ctl_read(sw, &ctl);
116         if (res)
117                 return res;
118         *val = 0;
119         for (i = 0; i < 8; i++) {
120                 *val <<= 1;
121                 res = tb_eeprom_transfer(sw, &ctl, TB_EEPROM_IN);
122                 if (res)
123                         return res;
124                 *val |= ctl.data_in;
125         }
126         return 0;
127 }
128
129 /**
130  * tb_eeprom_read_n - read count bytes from offset into val
131  */
132 static int tb_eeprom_read_n(struct tb_switch *sw, u16 offset, u8 *val,
133                 size_t count)
134 {
135         int i, res;
136         res = tb_eeprom_active(sw, true);
137         if (res)
138                 return res;
139         res = tb_eeprom_out(sw, 3);
140         if (res)
141                 return res;
142         res = tb_eeprom_out(sw, offset >> 8);
143         if (res)
144                 return res;
145         res = tb_eeprom_out(sw, offset);
146         if (res)
147                 return res;
148         for (i = 0; i < count; i++) {
149                 res = tb_eeprom_in(sw, val + i);
150                 if (res)
151                         return res;
152         }
153         return tb_eeprom_active(sw, false);
154 }
155
156 static u8 tb_crc8(u8 *data, int len)
157 {
158         int i, j;
159         u8 val = 0xff;
160         for (i = 0; i < len; i++) {
161                 val ^= data[i];
162                 for (j = 0; j < 8; j++)
163                         val = (val << 1) ^ ((val & 0x80) ? 7 : 0);
164         }
165         return val;
166 }
167
168 static u32 tb_crc32(void *data, size_t len)
169 {
170         return ~__crc32c_le(~0, data, len);
171 }
172
173 #define TB_DROM_DATA_START 13
174 struct tb_drom_header {
175         /* BYTE 0 */
176         u8 uid_crc8; /* checksum for uid */
177         /* BYTES 1-8 */
178         u64 uid;
179         /* BYTES 9-12 */
180         u32 data_crc32; /* checksum for data_len bytes starting at byte 13 */
181         /* BYTE 13 */
182         u8 device_rom_revision; /* should be <= 1 */
183         u16 data_len:10;
184         u8 __unknown1:6;
185         /* BYTES 16-21 */
186         u16 vendor_id;
187         u16 model_id;
188         u8 model_rev;
189         u8 eeprom_rev;
190 } __packed;
191
192 enum tb_drom_entry_type {
193         TB_DROM_ENTRY_GENERIC,
194         TB_DROM_ENTRY_PORT,
195 };
196
197 struct tb_drom_entry_header {
198         u8 len;
199         u8 index:6;
200         bool port_disabled:1; /* only valid if type is TB_DROM_ENTRY_PORT */
201         enum tb_drom_entry_type type:1;
202 } __packed;
203
204 struct tb_drom_entry_port {
205         /* BYTES 0-1 */
206         struct tb_drom_entry_header header;
207         /* BYTE 2 */
208         u8 dual_link_port_rid:4;
209         u8 link_nr:1;
210         u8 unknown1:2;
211         bool has_dual_link_port:1;
212
213         /* BYTE 3 */
214         u8 dual_link_port_nr:6;
215         u8 unknown2:2;
216
217         /* BYTES 4 - 5 TODO decode */
218         u8 micro2:4;
219         u8 micro1:4;
220         u8 micro3;
221
222         /* BYTES 5-6, TODO: verify (find hardware that has these set) */
223         u8 peer_port_rid:4;
224         u8 unknown3:3;
225         bool has_peer_port:1;
226         u8 peer_port_nr:6;
227         u8 unknown4:2;
228 } __packed;
229
230
231 /**
232  * tb_eeprom_get_drom_offset - get drom offset within eeprom
233  */
234 int tb_eeprom_get_drom_offset(struct tb_switch *sw, u16 *offset)
235 {
236         struct tb_cap_plug_events cap;
237         int res;
238         if (!sw->cap_plug_events) {
239                 tb_sw_warn(sw, "no TB_CAP_PLUG_EVENTS, cannot read eeprom\n");
240                 return -ENOSYS;
241         }
242         res = tb_sw_read(sw, &cap, TB_CFG_SWITCH, sw->cap_plug_events,
243                              sizeof(cap) / 4);
244         if (res)
245                 return res;
246
247         if (!cap.eeprom_ctl.present || cap.eeprom_ctl.not_present) {
248                 tb_sw_warn(sw, "no NVM\n");
249                 return -ENOSYS;
250         }
251
252         if (cap.drom_offset > 0xffff) {
253                 tb_sw_warn(sw, "drom offset is larger than 0xffff: %#x\n",
254                                 cap.drom_offset);
255                 return -ENXIO;
256         }
257         *offset = cap.drom_offset;
258         return 0;
259 }
260
261 /**
262  * tb_drom_read_uid_only - read uid directly from drom
263  *
264  * Does not use the cached copy in sw->drom. Used during resume to check switch
265  * identity.
266  */
267 int tb_drom_read_uid_only(struct tb_switch *sw, u64 *uid)
268 {
269         u8 data[9];
270         u16 drom_offset;
271         u8 crc;
272         int res = tb_eeprom_get_drom_offset(sw, &drom_offset);
273         if (res)
274                 return res;
275
276         /* read uid */
277         res = tb_eeprom_read_n(sw, drom_offset, data, 9);
278         if (res)
279                 return res;
280
281         crc = tb_crc8(data + 1, 8);
282         if (crc != data[0]) {
283                 tb_sw_warn(sw, "uid crc8 missmatch (expected: %#x, got: %#x)\n",
284                                 data[0], crc);
285                 return -EIO;
286         }
287
288         *uid = *(u64 *)(data+1);
289         return 0;
290 }
291
292 static void tb_drom_parse_port_entry(struct tb_port *port,
293                 struct tb_drom_entry_port *entry)
294 {
295         port->link_nr = entry->link_nr;
296         if (entry->has_dual_link_port)
297                 port->dual_link_port =
298                                 &port->sw->ports[entry->dual_link_port_nr];
299 }
300
301 static int tb_drom_parse_entry(struct tb_switch *sw,
302                 struct tb_drom_entry_header *header)
303 {
304         struct tb_port *port;
305         int res;
306         enum tb_port_type type;
307
308         if (header->type != TB_DROM_ENTRY_PORT)
309                 return 0;
310
311         port = &sw->ports[header->index];
312         port->disabled = header->port_disabled;
313         if (port->disabled)
314                 return 0;
315
316         res = tb_port_read(port, &type, TB_CFG_PORT, 2, 1);
317         if (res)
318                 return res;
319         type &= 0xffffff;
320
321         if (type == TB_TYPE_PORT) {
322                 struct tb_drom_entry_port *entry = (void *) header;
323                 if (header->len != sizeof(*entry)) {
324                         tb_sw_warn(sw,
325                                 "port entry has size %#x (expected %#lx)\n",
326                                 header->len, sizeof(struct tb_drom_entry_port));
327                         return -EIO;
328                 }
329                 tb_drom_parse_port_entry(port, entry);
330         }
331         return 0;
332 }
333
334 /**
335  * tb_drom_parse_entries - parse the linked list of drom entries
336  *
337  * Drom must have been copied to sw->drom.
338  */
339 static int tb_drom_parse_entries(struct tb_switch *sw)
340 {
341         struct tb_drom_header *header = (void *) sw->drom;
342         u16 pos = sizeof(*header);
343         u16 drom_size = header->data_len + TB_DROM_DATA_START;
344
345         while (pos < drom_size) {
346                 struct tb_drom_entry_header *entry = (void *) (sw->drom + pos);
347                 if (pos + 1 == drom_size || pos + entry->len > drom_size
348                                 || !entry->len) {
349                         tb_sw_warn(sw, "drom buffer overrun, aborting\n");
350                         return -EIO;
351                 }
352
353                 tb_drom_parse_entry(sw, entry);
354
355                 pos += entry->len;
356         }
357         return 0;
358 }
359
360 /**
361  * tb_drom_read - copy drom to sw->drom and parse it
362  */
363 int tb_drom_read(struct tb_switch *sw)
364 {
365         u16 drom_offset;
366         u16 size;
367         u32 crc;
368         struct tb_drom_header *header;
369         int res;
370         if (sw->drom)
371                 return 0;
372
373         if (tb_route(sw) == 0) {
374                 /*
375                  * The root switch contains only a dummy drom (header only,
376                  * no entries). Hardcode the configuration here.
377                  */
378                 tb_drom_read_uid_only(sw, &sw->uid);
379
380                 sw->ports[1].link_nr = 0;
381                 sw->ports[2].link_nr = 1;
382                 sw->ports[1].dual_link_port = &sw->ports[2];
383                 sw->ports[2].dual_link_port = &sw->ports[1];
384
385                 sw->ports[3].link_nr = 0;
386                 sw->ports[4].link_nr = 1;
387                 sw->ports[3].dual_link_port = &sw->ports[4];
388                 sw->ports[4].dual_link_port = &sw->ports[3];
389                 return 0;
390         }
391
392         res = tb_eeprom_get_drom_offset(sw, &drom_offset);
393         if (res)
394                 return res;
395
396         res = tb_eeprom_read_n(sw, drom_offset + 14, (u8 *) &size, 2);
397         if (res)
398                 return res;
399         size &= 0x3ff;
400         size += TB_DROM_DATA_START;
401         tb_sw_info(sw, "reading drom (length: %#x)\n", size);
402         if (size < sizeof(*header)) {
403                 tb_sw_warn(sw, "drom too small, aborting\n");
404                 return -EIO;
405         }
406
407         sw->drom = kzalloc(size, GFP_KERNEL);
408         if (!sw->drom)
409                 return -ENOMEM;
410         res = tb_eeprom_read_n(sw, drom_offset, sw->drom, size);
411         if (res)
412                 goto err;
413
414         header = (void *) sw->drom;
415
416         if (header->data_len + TB_DROM_DATA_START != size) {
417                 tb_sw_warn(sw, "drom size mismatch, aborting\n");
418                 goto err;
419         }
420
421         crc = tb_crc8((u8 *) &header->uid, 8);
422         if (crc != header->uid_crc8) {
423                 tb_sw_warn(sw,
424                         "drom uid crc8 mismatch (expected: %#x, got: %#x), aborting\n",
425                         header->uid_crc8, crc);
426                 goto err;
427         }
428         sw->uid = header->uid;
429
430         crc = tb_crc32(sw->drom + TB_DROM_DATA_START, header->data_len);
431         if (crc != header->data_crc32) {
432                 tb_sw_warn(sw,
433                         "drom data crc32 mismatch (expected: %#x, got: %#x), aborting\n",
434                         header->data_crc32, crc);
435                 goto err;
436         }
437
438         if (header->device_rom_revision > 1)
439                 tb_sw_warn(sw, "drom device_rom_revision %#x unknown\n",
440                         header->device_rom_revision);
441
442         return tb_drom_parse_entries(sw);
443 err:
444         kfree(sw->drom);
445         return -EIO;
446
447 }