Linux 3.9-rc8
[firefly-linux-kernel-4.4.55.git] / drivers / net / ethernet / qlogic / qlcnic / qlcnic_minidump.c
1 /*
2  * QLogic qlcnic NIC Driver
3  * Copyright (c) 2009-2013 QLogic Corporation
4  *
5  * See LICENSE.qlcnic for copyright and licensing details.
6  */
7
8 #include "qlcnic.h"
9 #include "qlcnic_hdr.h"
10 #include "qlcnic_83xx_hw.h"
11 #include "qlcnic_hw.h"
12
13 #include <net/ip.h>
14
15 #define QLC_83XX_MINIDUMP_FLASH         0x520000
16 #define QLC_83XX_OCM_INDEX                      3
17 #define QLC_83XX_PCI_INDEX                      0
18
19 static const u32 qlcnic_ms_read_data[] = {
20         0x410000A8, 0x410000AC, 0x410000B8, 0x410000BC
21 };
22
23 #define QLCNIC_DUMP_WCRB        BIT_0
24 #define QLCNIC_DUMP_RWCRB       BIT_1
25 #define QLCNIC_DUMP_ANDCRB      BIT_2
26 #define QLCNIC_DUMP_ORCRB       BIT_3
27 #define QLCNIC_DUMP_POLLCRB     BIT_4
28 #define QLCNIC_DUMP_RD_SAVE     BIT_5
29 #define QLCNIC_DUMP_WRT_SAVED   BIT_6
30 #define QLCNIC_DUMP_MOD_SAVE_ST BIT_7
31 #define QLCNIC_DUMP_SKIP        BIT_7
32
33 #define QLCNIC_DUMP_MASK_MAX    0xff
34
35 struct qlcnic_common_entry_hdr {
36         u32     type;
37         u32     offset;
38         u32     cap_size;
39         u8      mask;
40         u8      rsvd[2];
41         u8      flags;
42 } __packed;
43
44 struct __crb {
45         u32     addr;
46         u8      stride;
47         u8      rsvd1[3];
48         u32     data_size;
49         u32     no_ops;
50         u32     rsvd2[4];
51 } __packed;
52
53 struct __ctrl {
54         u32     addr;
55         u8      stride;
56         u8      index_a;
57         u16     timeout;
58         u32     data_size;
59         u32     no_ops;
60         u8      opcode;
61         u8      index_v;
62         u8      shl_val;
63         u8      shr_val;
64         u32     val1;
65         u32     val2;
66         u32     val3;
67 } __packed;
68
69 struct __cache {
70         u32     addr;
71         u16     stride;
72         u16     init_tag_val;
73         u32     size;
74         u32     no_ops;
75         u32     ctrl_addr;
76         u32     ctrl_val;
77         u32     read_addr;
78         u8      read_addr_stride;
79         u8      read_addr_num;
80         u8      rsvd1[2];
81 } __packed;
82
83 struct __ocm {
84         u8      rsvd[8];
85         u32     size;
86         u32     no_ops;
87         u8      rsvd1[8];
88         u32     read_addr;
89         u32     read_addr_stride;
90 } __packed;
91
92 struct __mem {
93         u8      rsvd[24];
94         u32     addr;
95         u32     size;
96 } __packed;
97
98 struct __mux {
99         u32     addr;
100         u8      rsvd[4];
101         u32     size;
102         u32     no_ops;
103         u32     val;
104         u32     val_stride;
105         u32     read_addr;
106         u8      rsvd2[4];
107 } __packed;
108
109 struct __queue {
110         u32     sel_addr;
111         u16     stride;
112         u8      rsvd[2];
113         u32     size;
114         u32     no_ops;
115         u8      rsvd2[8];
116         u32     read_addr;
117         u8      read_addr_stride;
118         u8      read_addr_cnt;
119         u8      rsvd3[2];
120 } __packed;
121
122 struct __pollrd {
123         u32     sel_addr;
124         u32     read_addr;
125         u32     sel_val;
126         u16     sel_val_stride;
127         u16     no_ops;
128         u32     poll_wait;
129         u32     poll_mask;
130         u32     data_size;
131         u8      rsvd[4];
132 } __packed;
133
134 struct __mux2 {
135         u32     sel_addr1;
136         u32     sel_addr2;
137         u32     sel_val1;
138         u32     sel_val2;
139         u32     no_ops;
140         u32     sel_val_mask;
141         u32     read_addr;
142         u8      sel_val_stride;
143         u8      data_size;
144         u8      rsvd[2];
145 } __packed;
146
147 struct __pollrdmwr {
148         u32     addr1;
149         u32     addr2;
150         u32     val1;
151         u32     val2;
152         u32     poll_wait;
153         u32     poll_mask;
154         u32     mod_mask;
155         u32     data_size;
156 } __packed;
157
158 struct qlcnic_dump_entry {
159         struct qlcnic_common_entry_hdr hdr;
160         union {
161                 struct __crb            crb;
162                 struct __cache          cache;
163                 struct __ocm            ocm;
164                 struct __mem            mem;
165                 struct __mux            mux;
166                 struct __queue          que;
167                 struct __ctrl           ctrl;
168                 struct __pollrdmwr      pollrdmwr;
169                 struct __mux2           mux2;
170                 struct __pollrd         pollrd;
171         } region;
172 } __packed;
173
174 enum qlcnic_minidump_opcode {
175         QLCNIC_DUMP_NOP         = 0,
176         QLCNIC_DUMP_READ_CRB    = 1,
177         QLCNIC_DUMP_READ_MUX    = 2,
178         QLCNIC_DUMP_QUEUE       = 3,
179         QLCNIC_DUMP_BRD_CONFIG  = 4,
180         QLCNIC_DUMP_READ_OCM    = 6,
181         QLCNIC_DUMP_PEG_REG     = 7,
182         QLCNIC_DUMP_L1_DTAG     = 8,
183         QLCNIC_DUMP_L1_ITAG     = 9,
184         QLCNIC_DUMP_L1_DATA     = 11,
185         QLCNIC_DUMP_L1_INST     = 12,
186         QLCNIC_DUMP_L2_DTAG     = 21,
187         QLCNIC_DUMP_L2_ITAG     = 22,
188         QLCNIC_DUMP_L2_DATA     = 23,
189         QLCNIC_DUMP_L2_INST     = 24,
190         QLCNIC_DUMP_POLL_RD     = 35,
191         QLCNIC_READ_MUX2        = 36,
192         QLCNIC_READ_POLLRDMWR   = 37,
193         QLCNIC_DUMP_READ_ROM    = 71,
194         QLCNIC_DUMP_READ_MEM    = 72,
195         QLCNIC_DUMP_READ_CTRL   = 98,
196         QLCNIC_DUMP_TLHDR       = 99,
197         QLCNIC_DUMP_RDEND       = 255
198 };
199
200 struct qlcnic_dump_operations {
201         enum qlcnic_minidump_opcode opcode;
202         u32 (*handler)(struct qlcnic_adapter *, struct qlcnic_dump_entry *,
203                        __le32 *);
204 };
205
206 static u32 qlcnic_dump_crb(struct qlcnic_adapter *adapter,
207                            struct qlcnic_dump_entry *entry, __le32 *buffer)
208 {
209         int i;
210         u32 addr, data;
211         struct __crb *crb = &entry->region.crb;
212
213         addr = crb->addr;
214
215         for (i = 0; i < crb->no_ops; i++) {
216                 data = qlcnic_ind_rd(adapter, addr);
217                 *buffer++ = cpu_to_le32(addr);
218                 *buffer++ = cpu_to_le32(data);
219                 addr += crb->stride;
220         }
221         return crb->no_ops * 2 * sizeof(u32);
222 }
223
224 static u32 qlcnic_dump_ctrl(struct qlcnic_adapter *adapter,
225                             struct qlcnic_dump_entry *entry, __le32 *buffer)
226 {
227         int i, k, timeout = 0;
228         u32 addr, data;
229         u8 no_ops;
230         struct __ctrl *ctr = &entry->region.ctrl;
231         struct qlcnic_dump_template_hdr *t_hdr = adapter->ahw->fw_dump.tmpl_hdr;
232
233         addr = ctr->addr;
234         no_ops = ctr->no_ops;
235
236         for (i = 0; i < no_ops; i++) {
237                 k = 0;
238                 for (k = 0; k < 8; k++) {
239                         if (!(ctr->opcode & (1 << k)))
240                                 continue;
241                         switch (1 << k) {
242                         case QLCNIC_DUMP_WCRB:
243                                 qlcnic_ind_wr(adapter, addr, ctr->val1);
244                                 break;
245                         case QLCNIC_DUMP_RWCRB:
246                                 data = qlcnic_ind_rd(adapter, addr);
247                                 qlcnic_ind_wr(adapter, addr, data);
248                                 break;
249                         case QLCNIC_DUMP_ANDCRB:
250                                 data = qlcnic_ind_rd(adapter, addr);
251                                 qlcnic_ind_wr(adapter, addr,
252                                               (data & ctr->val2));
253                                 break;
254                         case QLCNIC_DUMP_ORCRB:
255                                 data = qlcnic_ind_rd(adapter, addr);
256                                 qlcnic_ind_wr(adapter, addr,
257                                               (data | ctr->val3));
258                                 break;
259                         case QLCNIC_DUMP_POLLCRB:
260                                 while (timeout <= ctr->timeout) {
261                                         data = qlcnic_ind_rd(adapter, addr);
262                                         if ((data & ctr->val2) == ctr->val1)
263                                                 break;
264                                         usleep_range(1000, 2000);
265                                         timeout++;
266                                 }
267                                 if (timeout > ctr->timeout) {
268                                         dev_info(&adapter->pdev->dev,
269                                         "Timed out, aborting poll CRB\n");
270                                         return -EINVAL;
271                                 }
272                                 break;
273                         case QLCNIC_DUMP_RD_SAVE:
274                                 if (ctr->index_a)
275                                         addr = t_hdr->saved_state[ctr->index_a];
276                                 data = qlcnic_ind_rd(adapter, addr);
277                                 t_hdr->saved_state[ctr->index_v] = data;
278                                 break;
279                         case QLCNIC_DUMP_WRT_SAVED:
280                                 if (ctr->index_v)
281                                         data = t_hdr->saved_state[ctr->index_v];
282                                 else
283                                         data = ctr->val1;
284                                 if (ctr->index_a)
285                                         addr = t_hdr->saved_state[ctr->index_a];
286                                 qlcnic_ind_wr(adapter, addr, data);
287                                 break;
288                         case QLCNIC_DUMP_MOD_SAVE_ST:
289                                 data = t_hdr->saved_state[ctr->index_v];
290                                 data <<= ctr->shl_val;
291                                 data >>= ctr->shr_val;
292                                 if (ctr->val2)
293                                         data &= ctr->val2;
294                                 data |= ctr->val3;
295                                 data += ctr->val1;
296                                 t_hdr->saved_state[ctr->index_v] = data;
297                                 break;
298                         default:
299                                 dev_info(&adapter->pdev->dev,
300                                          "Unknown opcode\n");
301                                 break;
302                         }
303                 }
304                 addr += ctr->stride;
305         }
306         return 0;
307 }
308
309 static u32 qlcnic_dump_mux(struct qlcnic_adapter *adapter,
310                            struct qlcnic_dump_entry *entry, __le32 *buffer)
311 {
312         int loop;
313         u32 val, data = 0;
314         struct __mux *mux = &entry->region.mux;
315
316         val = mux->val;
317         for (loop = 0; loop < mux->no_ops; loop++) {
318                 qlcnic_ind_wr(adapter, mux->addr, val);
319                 data = qlcnic_ind_rd(adapter, mux->read_addr);
320                 *buffer++ = cpu_to_le32(val);
321                 *buffer++ = cpu_to_le32(data);
322                 val += mux->val_stride;
323         }
324         return 2 * mux->no_ops * sizeof(u32);
325 }
326
327 static u32 qlcnic_dump_que(struct qlcnic_adapter *adapter,
328                            struct qlcnic_dump_entry *entry, __le32 *buffer)
329 {
330         int i, loop;
331         u32 cnt, addr, data, que_id = 0;
332         struct __queue *que = &entry->region.que;
333
334         addr = que->read_addr;
335         cnt = que->read_addr_cnt;
336
337         for (loop = 0; loop < que->no_ops; loop++) {
338                 qlcnic_ind_wr(adapter, que->sel_addr, que_id);
339                 addr = que->read_addr;
340                 for (i = 0; i < cnt; i++) {
341                         data = qlcnic_ind_rd(adapter, addr);
342                         *buffer++ = cpu_to_le32(data);
343                         addr += que->read_addr_stride;
344                 }
345                 que_id += que->stride;
346         }
347         return que->no_ops * cnt * sizeof(u32);
348 }
349
350 static u32 qlcnic_dump_ocm(struct qlcnic_adapter *adapter,
351                            struct qlcnic_dump_entry *entry, __le32 *buffer)
352 {
353         int i;
354         u32 data;
355         void __iomem *addr;
356         struct __ocm *ocm = &entry->region.ocm;
357
358         addr = adapter->ahw->pci_base0 + ocm->read_addr;
359         for (i = 0; i < ocm->no_ops; i++) {
360                 data = readl(addr);
361                 *buffer++ = cpu_to_le32(data);
362                 addr += ocm->read_addr_stride;
363         }
364         return ocm->no_ops * sizeof(u32);
365 }
366
367 static u32 qlcnic_read_rom(struct qlcnic_adapter *adapter,
368                            struct qlcnic_dump_entry *entry, __le32 *buffer)
369 {
370         int i, count = 0;
371         u32 fl_addr, size, val, lck_val, addr;
372         struct __mem *rom = &entry->region.mem;
373
374         fl_addr = rom->addr;
375         size = rom->size / 4;
376 lock_try:
377         lck_val = QLC_SHARED_REG_RD32(adapter, QLCNIC_FLASH_LOCK);
378         if (!lck_val && count < MAX_CTL_CHECK) {
379                 usleep_range(10000, 11000);
380                 count++;
381                 goto lock_try;
382         }
383         QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER,
384                             adapter->ahw->pci_func);
385         for (i = 0; i < size; i++) {
386                 addr = fl_addr & 0xFFFF0000;
387                 qlcnic_ind_wr(adapter, FLASH_ROM_WINDOW, addr);
388                 addr = LSW(fl_addr) + FLASH_ROM_DATA;
389                 val = qlcnic_ind_rd(adapter, addr);
390                 fl_addr += 4;
391                 *buffer++ = cpu_to_le32(val);
392         }
393         QLC_SHARED_REG_RD32(adapter, QLCNIC_FLASH_UNLOCK);
394         return rom->size;
395 }
396
397 static u32 qlcnic_dump_l1_cache(struct qlcnic_adapter *adapter,
398                                 struct qlcnic_dump_entry *entry, __le32 *buffer)
399 {
400         int i;
401         u32 cnt, val, data, addr;
402         struct __cache *l1 = &entry->region.cache;
403
404         val = l1->init_tag_val;
405
406         for (i = 0; i < l1->no_ops; i++) {
407                 qlcnic_ind_wr(adapter, l1->addr, val);
408                 qlcnic_ind_wr(adapter, l1->ctrl_addr, LSW(l1->ctrl_val));
409                 addr = l1->read_addr;
410                 cnt = l1->read_addr_num;
411                 while (cnt) {
412                         data = qlcnic_ind_rd(adapter, addr);
413                         *buffer++ = cpu_to_le32(data);
414                         addr += l1->read_addr_stride;
415                         cnt--;
416                 }
417                 val += l1->stride;
418         }
419         return l1->no_ops * l1->read_addr_num * sizeof(u32);
420 }
421
422 static u32 qlcnic_dump_l2_cache(struct qlcnic_adapter *adapter,
423                                 struct qlcnic_dump_entry *entry, __le32 *buffer)
424 {
425         int i;
426         u32 cnt, val, data, addr;
427         u8 poll_mask, poll_to, time_out = 0;
428         struct __cache *l2 = &entry->region.cache;
429
430         val = l2->init_tag_val;
431         poll_mask = LSB(MSW(l2->ctrl_val));
432         poll_to = MSB(MSW(l2->ctrl_val));
433
434         for (i = 0; i < l2->no_ops; i++) {
435                 qlcnic_ind_wr(adapter, l2->addr, val);
436                 if (LSW(l2->ctrl_val))
437                         qlcnic_ind_wr(adapter, l2->ctrl_addr,
438                                       LSW(l2->ctrl_val));
439                 if (!poll_mask)
440                         goto skip_poll;
441                 do {
442                         data = qlcnic_ind_rd(adapter, l2->ctrl_addr);
443                         if (!(data & poll_mask))
444                                 break;
445                         usleep_range(1000, 2000);
446                         time_out++;
447                 } while (time_out <= poll_to);
448
449                 if (time_out > poll_to) {
450                         dev_err(&adapter->pdev->dev,
451                                 "Timeout exceeded in %s, aborting dump\n",
452                                 __func__);
453                         return -EINVAL;
454                 }
455 skip_poll:
456                 addr = l2->read_addr;
457                 cnt = l2->read_addr_num;
458                 while (cnt) {
459                         data = qlcnic_ind_rd(adapter, addr);
460                         *buffer++ = cpu_to_le32(data);
461                         addr += l2->read_addr_stride;
462                         cnt--;
463                 }
464                 val += l2->stride;
465         }
466         return l2->no_ops * l2->read_addr_num * sizeof(u32);
467 }
468
469 static u32 qlcnic_read_memory(struct qlcnic_adapter *adapter,
470                               struct qlcnic_dump_entry *entry, __le32 *buffer)
471 {
472         u32 addr, data, test, ret = 0;
473         int i, reg_read;
474         struct __mem *mem = &entry->region.mem;
475
476         reg_read = mem->size;
477         addr = mem->addr;
478         /* check for data size of multiple of 16 and 16 byte alignment */
479         if ((addr & 0xf) || (reg_read%16)) {
480                 dev_info(&adapter->pdev->dev,
481                          "Unaligned memory addr:0x%x size:0x%x\n",
482                          addr, reg_read);
483                 return -EINVAL;
484         }
485
486         mutex_lock(&adapter->ahw->mem_lock);
487
488         while (reg_read != 0) {
489                 qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_LO, addr);
490                 qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_HI, 0);
491                 qlcnic_ind_wr(adapter, QLCNIC_MS_CTRL, QLCNIC_TA_START_ENABLE);
492
493                 for (i = 0; i < MAX_CTL_CHECK; i++) {
494                         test = qlcnic_ind_rd(adapter, QLCNIC_MS_CTRL);
495                         if (!(test & TA_CTL_BUSY))
496                                 break;
497                 }
498                 if (i == MAX_CTL_CHECK) {
499                         if (printk_ratelimit()) {
500                                 dev_err(&adapter->pdev->dev,
501                                         "failed to read through agent\n");
502                                 ret = -EINVAL;
503                                 goto out;
504                         }
505                 }
506                 for (i = 0; i < 4; i++) {
507                         data = qlcnic_ind_rd(adapter, qlcnic_ms_read_data[i]);
508                         *buffer++ = cpu_to_le32(data);
509                 }
510                 addr += 16;
511                 reg_read -= 16;
512                 ret += 16;
513         }
514 out:
515         mutex_unlock(&adapter->ahw->mem_lock);
516         return mem->size;
517 }
518
519 static u32 qlcnic_dump_nop(struct qlcnic_adapter *adapter,
520                            struct qlcnic_dump_entry *entry, __le32 *buffer)
521 {
522         entry->hdr.flags |= QLCNIC_DUMP_SKIP;
523         return 0;
524 }
525
526 static int qlcnic_valid_dump_entry(struct device *dev,
527                                    struct qlcnic_dump_entry *entry, u32 size)
528 {
529         int ret = 1;
530         if (size != entry->hdr.cap_size) {
531                 dev_err(dev,
532                         "Invalid entry, Type:%d\tMask:%d\tSize:%dCap_size:%d\n",
533                         entry->hdr.type, entry->hdr.mask, size,
534                         entry->hdr.cap_size);
535                 ret = 0;
536         }
537         return ret;
538 }
539
540 static u32 qlcnic_read_pollrdmwr(struct qlcnic_adapter *adapter,
541                                  struct qlcnic_dump_entry *entry,
542                                  __le32 *buffer)
543 {
544         struct __pollrdmwr *poll = &entry->region.pollrdmwr;
545         u32 data, wait_count, poll_wait, temp;
546
547         poll_wait = poll->poll_wait;
548
549         qlcnic_ind_wr(adapter, poll->addr1, poll->val1);
550         wait_count = 0;
551
552         while (wait_count < poll_wait) {
553                 data = qlcnic_ind_rd(adapter, poll->addr1);
554                 if ((data & poll->poll_mask) != 0)
555                         break;
556                 wait_count++;
557         }
558
559         if (wait_count == poll_wait) {
560                 dev_err(&adapter->pdev->dev,
561                         "Timeout exceeded in %s, aborting dump\n",
562                         __func__);
563                 return 0;
564         }
565
566         data = qlcnic_ind_rd(adapter, poll->addr2) & poll->mod_mask;
567         qlcnic_ind_wr(adapter, poll->addr2, data);
568         qlcnic_ind_wr(adapter, poll->addr1, poll->val2);
569         wait_count = 0;
570
571         while (wait_count < poll_wait) {
572                 temp = qlcnic_ind_rd(adapter, poll->addr1);
573                 if ((temp & poll->poll_mask) != 0)
574                         break;
575                 wait_count++;
576         }
577
578         *buffer++ = cpu_to_le32(poll->addr2);
579         *buffer++ = cpu_to_le32(data);
580
581         return 2 * sizeof(u32);
582
583 }
584
585 static u32 qlcnic_read_pollrd(struct qlcnic_adapter *adapter,
586                               struct qlcnic_dump_entry *entry, __le32 *buffer)
587 {
588         struct __pollrd *pollrd = &entry->region.pollrd;
589         u32 data, wait_count, poll_wait, sel_val;
590         int i;
591
592         poll_wait = pollrd->poll_wait;
593         sel_val = pollrd->sel_val;
594
595         for (i = 0; i < pollrd->no_ops; i++) {
596                 qlcnic_ind_wr(adapter, pollrd->sel_addr, sel_val);
597                 wait_count = 0;
598                 while (wait_count < poll_wait) {
599                         data = qlcnic_ind_rd(adapter, pollrd->sel_addr);
600                         if ((data & pollrd->poll_mask) != 0)
601                                 break;
602                         wait_count++;
603                 }
604
605                 if (wait_count == poll_wait) {
606                         dev_err(&adapter->pdev->dev,
607                                 "Timeout exceeded in %s, aborting dump\n",
608                                 __func__);
609                         return 0;
610                 }
611
612                 data = qlcnic_ind_rd(adapter, pollrd->read_addr);
613                 *buffer++ = cpu_to_le32(sel_val);
614                 *buffer++ = cpu_to_le32(data);
615                 sel_val += pollrd->sel_val_stride;
616         }
617         return pollrd->no_ops * (2 * sizeof(u32));
618 }
619
620 static u32 qlcnic_read_mux2(struct qlcnic_adapter *adapter,
621                             struct qlcnic_dump_entry *entry, __le32 *buffer)
622 {
623         struct __mux2 *mux2 = &entry->region.mux2;
624         u32 data;
625         u32 t_sel_val, sel_val1, sel_val2;
626         int i;
627
628         sel_val1 = mux2->sel_val1;
629         sel_val2 = mux2->sel_val2;
630
631         for (i = 0; i < mux2->no_ops; i++) {
632                 qlcnic_ind_wr(adapter, mux2->sel_addr1, sel_val1);
633                 t_sel_val = sel_val1 & mux2->sel_val_mask;
634                 qlcnic_ind_wr(adapter, mux2->sel_addr2, t_sel_val);
635                 data = qlcnic_ind_rd(adapter, mux2->read_addr);
636                 *buffer++ = cpu_to_le32(t_sel_val);
637                 *buffer++ = cpu_to_le32(data);
638                 qlcnic_ind_wr(adapter, mux2->sel_addr1, sel_val2);
639                 t_sel_val = sel_val2 & mux2->sel_val_mask;
640                 qlcnic_ind_wr(adapter, mux2->sel_addr2, t_sel_val);
641                 data = qlcnic_ind_rd(adapter, mux2->read_addr);
642                 *buffer++ = cpu_to_le32(t_sel_val);
643                 *buffer++ = cpu_to_le32(data);
644                 sel_val1 += mux2->sel_val_stride;
645                 sel_val2 += mux2->sel_val_stride;
646         }
647
648         return mux2->no_ops * (4 * sizeof(u32));
649 }
650
651 static u32 qlcnic_83xx_dump_rom(struct qlcnic_adapter *adapter,
652                                 struct qlcnic_dump_entry *entry, __le32 *buffer)
653 {
654         u32 fl_addr, size;
655         struct __mem *rom = &entry->region.mem;
656
657         fl_addr = rom->addr;
658         size = rom->size / 4;
659
660         if (!qlcnic_83xx_lockless_flash_read32(adapter, fl_addr,
661                                                (u8 *)buffer, size))
662                 return rom->size;
663
664         return 0;
665 }
666
667 static const struct qlcnic_dump_operations qlcnic_fw_dump_ops[] = {
668         {QLCNIC_DUMP_NOP, qlcnic_dump_nop},
669         {QLCNIC_DUMP_READ_CRB, qlcnic_dump_crb},
670         {QLCNIC_DUMP_READ_MUX, qlcnic_dump_mux},
671         {QLCNIC_DUMP_QUEUE, qlcnic_dump_que},
672         {QLCNIC_DUMP_BRD_CONFIG, qlcnic_read_rom},
673         {QLCNIC_DUMP_READ_OCM, qlcnic_dump_ocm},
674         {QLCNIC_DUMP_PEG_REG, qlcnic_dump_ctrl},
675         {QLCNIC_DUMP_L1_DTAG, qlcnic_dump_l1_cache},
676         {QLCNIC_DUMP_L1_ITAG, qlcnic_dump_l1_cache},
677         {QLCNIC_DUMP_L1_DATA, qlcnic_dump_l1_cache},
678         {QLCNIC_DUMP_L1_INST, qlcnic_dump_l1_cache},
679         {QLCNIC_DUMP_L2_DTAG, qlcnic_dump_l2_cache},
680         {QLCNIC_DUMP_L2_ITAG, qlcnic_dump_l2_cache},
681         {QLCNIC_DUMP_L2_DATA, qlcnic_dump_l2_cache},
682         {QLCNIC_DUMP_L2_INST, qlcnic_dump_l2_cache},
683         {QLCNIC_DUMP_READ_ROM, qlcnic_read_rom},
684         {QLCNIC_DUMP_READ_MEM, qlcnic_read_memory},
685         {QLCNIC_DUMP_READ_CTRL, qlcnic_dump_ctrl},
686         {QLCNIC_DUMP_TLHDR, qlcnic_dump_nop},
687         {QLCNIC_DUMP_RDEND, qlcnic_dump_nop},
688 };
689
690 static const struct qlcnic_dump_operations qlcnic_83xx_fw_dump_ops[] = {
691         {QLCNIC_DUMP_NOP, qlcnic_dump_nop},
692         {QLCNIC_DUMP_READ_CRB, qlcnic_dump_crb},
693         {QLCNIC_DUMP_READ_MUX, qlcnic_dump_mux},
694         {QLCNIC_DUMP_QUEUE, qlcnic_dump_que},
695         {QLCNIC_DUMP_BRD_CONFIG, qlcnic_83xx_dump_rom},
696         {QLCNIC_DUMP_READ_OCM, qlcnic_dump_ocm},
697         {QLCNIC_DUMP_PEG_REG, qlcnic_dump_ctrl},
698         {QLCNIC_DUMP_L1_DTAG, qlcnic_dump_l1_cache},
699         {QLCNIC_DUMP_L1_ITAG, qlcnic_dump_l1_cache},
700         {QLCNIC_DUMP_L1_DATA, qlcnic_dump_l1_cache},
701         {QLCNIC_DUMP_L1_INST, qlcnic_dump_l1_cache},
702         {QLCNIC_DUMP_L2_DTAG, qlcnic_dump_l2_cache},
703         {QLCNIC_DUMP_L2_ITAG, qlcnic_dump_l2_cache},
704         {QLCNIC_DUMP_L2_DATA, qlcnic_dump_l2_cache},
705         {QLCNIC_DUMP_L2_INST, qlcnic_dump_l2_cache},
706         {QLCNIC_DUMP_POLL_RD, qlcnic_read_pollrd},
707         {QLCNIC_READ_MUX2, qlcnic_read_mux2},
708         {QLCNIC_READ_POLLRDMWR, qlcnic_read_pollrdmwr},
709         {QLCNIC_DUMP_READ_ROM, qlcnic_83xx_dump_rom},
710         {QLCNIC_DUMP_READ_MEM, qlcnic_read_memory},
711         {QLCNIC_DUMP_READ_CTRL, qlcnic_dump_ctrl},
712         {QLCNIC_DUMP_TLHDR, qlcnic_dump_nop},
713         {QLCNIC_DUMP_RDEND, qlcnic_dump_nop},
714 };
715
716 static uint32_t qlcnic_temp_checksum(uint32_t *temp_buffer, u32 temp_size)
717 {
718         uint64_t sum = 0;
719         int count = temp_size / sizeof(uint32_t);
720         while (count-- > 0)
721                 sum += *temp_buffer++;
722         while (sum >> 32)
723                 sum = (sum & 0xFFFFFFFF) + (sum >> 32);
724         return ~sum;
725 }
726
727 static int qlcnic_fw_flash_get_minidump_temp(struct qlcnic_adapter *adapter,
728                                              u8 *buffer, u32 size)
729 {
730         int ret = 0;
731
732         if (qlcnic_82xx_check(adapter))
733                 return -EIO;
734
735         if (qlcnic_83xx_lock_flash(adapter))
736                 return -EIO;
737
738         ret = qlcnic_83xx_lockless_flash_read32(adapter,
739                                                 QLC_83XX_MINIDUMP_FLASH,
740                                                 buffer, size / sizeof(u32));
741
742         qlcnic_83xx_unlock_flash(adapter);
743
744         return ret;
745 }
746
747 static int
748 qlcnic_fw_flash_get_minidump_temp_size(struct qlcnic_adapter *adapter,
749                                        struct qlcnic_cmd_args *cmd)
750 {
751         struct qlcnic_dump_template_hdr tmp_hdr;
752         u32 size = sizeof(struct qlcnic_dump_template_hdr) / sizeof(u32);
753         int ret = 0;
754
755         if (qlcnic_82xx_check(adapter))
756                 return -EIO;
757
758         if (qlcnic_83xx_lock_flash(adapter))
759                 return -EIO;
760
761         ret = qlcnic_83xx_lockless_flash_read32(adapter,
762                                                 QLC_83XX_MINIDUMP_FLASH,
763                                                 (u8 *)&tmp_hdr, size);
764
765         qlcnic_83xx_unlock_flash(adapter);
766
767         cmd->rsp.arg[2] = tmp_hdr.size;
768         cmd->rsp.arg[3] = tmp_hdr.version;
769
770         return ret;
771 }
772
773 static int qlcnic_fw_get_minidump_temp_size(struct qlcnic_adapter *adapter,
774                                             u32 *version, u32 *temp_size,
775                                             u8 *use_flash_temp)
776 {
777         int err = 0;
778         struct qlcnic_cmd_args cmd;
779
780         if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_TEMP_SIZE))
781                 return -ENOMEM;
782
783         err = qlcnic_issue_cmd(adapter, &cmd);
784         if (err != QLCNIC_RCODE_SUCCESS) {
785                 if (qlcnic_fw_flash_get_minidump_temp_size(adapter, &cmd)) {
786                         qlcnic_free_mbx_args(&cmd);
787                         return -EIO;
788                 }
789                 *use_flash_temp = 1;
790         }
791
792         *temp_size = cmd.rsp.arg[2];
793         *version = cmd.rsp.arg[3];
794         qlcnic_free_mbx_args(&cmd);
795
796         if (!(*temp_size))
797                 return -EIO;
798
799         return 0;
800 }
801
802 static int __qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter,
803                                              u32 *buffer, u32 temp_size)
804 {
805         int err = 0, i;
806         void *tmp_addr;
807         __le32 *tmp_buf;
808         struct qlcnic_cmd_args cmd;
809         dma_addr_t tmp_addr_t = 0;
810
811         tmp_addr = dma_alloc_coherent(&adapter->pdev->dev, temp_size,
812                                       &tmp_addr_t, GFP_KERNEL);
813         if (!tmp_addr) {
814                 dev_err(&adapter->pdev->dev,
815                         "Can't get memory for FW dump template\n");
816                 return -ENOMEM;
817         }
818
819         if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_TEMP_HDR)) {
820                 err = -ENOMEM;
821                 goto free_mem;
822         }
823
824         cmd.req.arg[1] = LSD(tmp_addr_t);
825         cmd.req.arg[2] = MSD(tmp_addr_t);
826         cmd.req.arg[3] = temp_size;
827         err = qlcnic_issue_cmd(adapter, &cmd);
828
829         tmp_buf = tmp_addr;
830         if (err == QLCNIC_RCODE_SUCCESS) {
831                 for (i = 0; i < temp_size / sizeof(u32); i++)
832                         *buffer++ = __le32_to_cpu(*tmp_buf++);
833         }
834
835         qlcnic_free_mbx_args(&cmd);
836
837 free_mem:
838         dma_free_coherent(&adapter->pdev->dev, temp_size, tmp_addr, tmp_addr_t);
839
840         return err;
841 }
842
843 int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter)
844 {
845         int err;
846         u32 temp_size = 0;
847         u32 version, csum, *tmp_buf;
848         struct qlcnic_hardware_context *ahw;
849         struct qlcnic_dump_template_hdr *tmpl_hdr;
850         u8 use_flash_temp = 0;
851
852         ahw = adapter->ahw;
853
854         err = qlcnic_fw_get_minidump_temp_size(adapter, &version, &temp_size,
855                                                &use_flash_temp);
856         if (err) {
857                 dev_err(&adapter->pdev->dev,
858                         "Can't get template size %d\n", err);
859                 return -EIO;
860         }
861
862         ahw->fw_dump.tmpl_hdr = vzalloc(temp_size);
863         if (!ahw->fw_dump.tmpl_hdr)
864                 return -ENOMEM;
865
866         tmp_buf = (u32 *)ahw->fw_dump.tmpl_hdr;
867         if (use_flash_temp)
868                 goto flash_temp;
869
870         err = __qlcnic_fw_cmd_get_minidump_temp(adapter, tmp_buf, temp_size);
871
872         if (err) {
873 flash_temp:
874                 err = qlcnic_fw_flash_get_minidump_temp(adapter, (u8 *)tmp_buf,
875                                                         temp_size);
876
877                 if (err) {
878                         dev_err(&adapter->pdev->dev,
879                                 "Failed to get minidump template header %d\n",
880                                 err);
881                         vfree(ahw->fw_dump.tmpl_hdr);
882                         ahw->fw_dump.tmpl_hdr = NULL;
883                         return -EIO;
884                 }
885         }
886
887         csum = qlcnic_temp_checksum((uint32_t *)tmp_buf, temp_size);
888
889         if (csum) {
890                 dev_err(&adapter->pdev->dev,
891                         "Template header checksum validation failed\n");
892                 vfree(ahw->fw_dump.tmpl_hdr);
893                 ahw->fw_dump.tmpl_hdr = NULL;
894                 return -EIO;
895         }
896
897         tmpl_hdr = ahw->fw_dump.tmpl_hdr;
898         tmpl_hdr->drv_cap_mask = QLCNIC_DUMP_MASK_DEF;
899         ahw->fw_dump.enable = 1;
900
901         return 0;
902 }
903
904 int qlcnic_dump_fw(struct qlcnic_adapter *adapter)
905 {
906         __le32 *buffer;
907         u32 ocm_window;
908         char mesg[64];
909         char *msg[] = {mesg, NULL};
910         int i, k, ops_cnt, ops_index, dump_size = 0;
911         u32 entry_offset, dump, no_entries, buf_offset = 0;
912         struct qlcnic_dump_entry *entry;
913         struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
914         struct qlcnic_dump_template_hdr *tmpl_hdr = fw_dump->tmpl_hdr;
915         static const struct qlcnic_dump_operations *fw_dump_ops;
916         struct qlcnic_hardware_context *ahw;
917
918         ahw = adapter->ahw;
919
920         if (!fw_dump->enable) {
921                 dev_info(&adapter->pdev->dev, "Dump not enabled\n");
922                 return -EIO;
923         }
924
925         if (fw_dump->clr) {
926                 dev_info(&adapter->pdev->dev,
927                          "Previous dump not cleared, not capturing dump\n");
928                 return -EIO;
929         }
930
931         netif_info(adapter->ahw, drv, adapter->netdev, "Take FW dump\n");
932         /* Calculate the size for dump data area only */
933         for (i = 2, k = 1; (i & QLCNIC_DUMP_MASK_MAX); i <<= 1, k++)
934                 if (i & tmpl_hdr->drv_cap_mask)
935                         dump_size += tmpl_hdr->cap_sizes[k];
936         if (!dump_size)
937                 return -EIO;
938
939         fw_dump->data = vzalloc(dump_size);
940         if (!fw_dump->data)
941                 return -ENOMEM;
942
943         buffer = fw_dump->data;
944         fw_dump->size = dump_size;
945         no_entries = tmpl_hdr->num_entries;
946         entry_offset = tmpl_hdr->offset;
947         tmpl_hdr->sys_info[0] = QLCNIC_DRIVER_VERSION;
948         tmpl_hdr->sys_info[1] = adapter->fw_version;
949
950         if (qlcnic_82xx_check(adapter)) {
951                 ops_cnt = ARRAY_SIZE(qlcnic_fw_dump_ops);
952                 fw_dump_ops = qlcnic_fw_dump_ops;
953         } else {
954                 ops_cnt = ARRAY_SIZE(qlcnic_83xx_fw_dump_ops);
955                 fw_dump_ops = qlcnic_83xx_fw_dump_ops;
956                 ocm_window = tmpl_hdr->ocm_wnd_reg[adapter->ahw->pci_func];
957                 tmpl_hdr->saved_state[QLC_83XX_OCM_INDEX] = ocm_window;
958                 tmpl_hdr->saved_state[QLC_83XX_PCI_INDEX] = ahw->pci_func;
959         }
960
961         for (i = 0; i < no_entries; i++) {
962                 entry = (void *)tmpl_hdr + entry_offset;
963                 if (!(entry->hdr.mask & tmpl_hdr->drv_cap_mask)) {
964                         entry->hdr.flags |= QLCNIC_DUMP_SKIP;
965                         entry_offset += entry->hdr.offset;
966                         continue;
967                 }
968
969                 /* Find the handler for this entry */
970                 ops_index = 0;
971                 while (ops_index < ops_cnt) {
972                         if (entry->hdr.type == fw_dump_ops[ops_index].opcode)
973                                 break;
974                         ops_index++;
975                 }
976
977                 if (ops_index == ops_cnt) {
978                         dev_info(&adapter->pdev->dev,
979                                  "Invalid entry type %d, exiting dump\n",
980                                  entry->hdr.type);
981                         goto error;
982                 }
983
984                 /* Collect dump for this entry */
985                 dump = fw_dump_ops[ops_index].handler(adapter, entry, buffer);
986                 if (!qlcnic_valid_dump_entry(&adapter->pdev->dev, entry, dump))
987                         entry->hdr.flags |= QLCNIC_DUMP_SKIP;
988                 buf_offset += entry->hdr.cap_size;
989                 entry_offset += entry->hdr.offset;
990                 buffer = fw_dump->data + buf_offset;
991         }
992         if (dump_size != buf_offset) {
993                 dev_info(&adapter->pdev->dev,
994                          "Captured(%d) and expected size(%d) do not match\n",
995                          buf_offset, dump_size);
996                 goto error;
997         } else {
998                 fw_dump->clr = 1;
999                 snprintf(mesg, sizeof(mesg), "FW_DUMP=%s",
1000                          adapter->netdev->name);
1001                 dev_info(&adapter->pdev->dev, "%s: Dump data, %d bytes captured\n",
1002                          adapter->netdev->name, fw_dump->size);
1003                 /* Send a udev event to notify availability of FW dump */
1004                 kobject_uevent_env(&adapter->pdev->dev.kobj, KOBJ_CHANGE, msg);
1005                 return 0;
1006         }
1007 error:
1008         vfree(fw_dump->data);
1009         return -EINVAL;
1010 }
1011
1012 void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *adapter)
1013 {
1014         u32 prev_version, current_version;
1015         struct qlcnic_hardware_context *ahw = adapter->ahw;
1016         struct qlcnic_fw_dump *fw_dump = &ahw->fw_dump;
1017         struct pci_dev *pdev = adapter->pdev;
1018
1019         prev_version = adapter->fw_version;
1020         current_version = qlcnic_83xx_get_fw_version(adapter);
1021
1022         if (fw_dump->tmpl_hdr == NULL || current_version > prev_version) {
1023                 if (fw_dump->tmpl_hdr)
1024                         vfree(fw_dump->tmpl_hdr);
1025                 if (!qlcnic_fw_cmd_get_minidump_temp(adapter))
1026                         dev_info(&pdev->dev, "Supports FW dump capability\n");
1027         }
1028 }