xref: /illumos-gate/usr/src/uts/common/io/bnx/570x/driver/common/lmdev/bnx_hw_reset.c (revision eef4f27b270242808b43b4b23bd161df52839361)
1 /*
2  * Copyright 2014-2017 Cavium, Inc.
3  * The contents of this file are subject to the terms of the Common Development
4  * and Distribution License, v.1,  (the "License").
5  *
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the License at available
9  * at http://opensource.org/licenses/CDDL-1.0
10  *
11  * See the License for the specific language governing permissions and
12  * limitations under the License.
13  */
14 
15 
16 #include "lm5706.h"
17 
18 
19 
20 /*******************************************************************************
21  * Description:
22  *
23  * Return:
24  ******************************************************************************/
25 u8_t
26 fw_reset_sync(
27     lm_device_t *pdev,
28     lm_reason_t reason,
29     u32_t msg_data,
30     u32_t fw_ack_timeout_us)    /* timeout in microseconds. */
31 {
32     u32_t cnt;
33     u32_t val;
34 
35     /* Skip handshake for 5709 for emulation */
36     if (CHIP_ID(pdev) == CHIP_ID_5709_IKOS)
37     {
38         return TRUE;
39     }
40 
41     /* If we timed out, inform the firmware that this is the case. */
42     if(pdev->vars.fw_timed_out)
43     {
44         return TRUE;
45     }
46 
47     pdev->vars.fw_wr_seq++;
48     msg_data |= (pdev->vars.fw_wr_seq & DRV_MSG_SEQ);
49 
50     switch(reason)
51     {
52         case LM_REASON_DRIVER_RESET:
53             msg_data |= DRV_MSG_CODE_RESET;
54             break;
55 
56         case LM_REASON_DRIVER_UNLOAD:
57             msg_data |= DRV_MSG_CODE_UNLOAD;
58             break;
59 
60         case LM_REASON_DRIVER_UNLOAD_POWER_DOWN:
61             msg_data |= DRV_MSG_CODE_UNLOAD_LNK_DN;
62             break;
63 
64         case LM_REASON_DRIVER_SHUTDOWN:
65             msg_data |= DRV_MSG_CODE_SHUTDOWN;
66             break;
67 
68         case LM_REASON_WOL_SUSPEND:
69             msg_data |= DRV_MSG_CODE_SUSPEND_WOL;
70             break;
71 
72         case LM_REASON_NO_WOL_SUSPEND:
73             msg_data |= DRV_MSG_CODE_SUSPEND_NO_WOL;
74             break;
75 
76         case LM_REASON_DIAG:
77             msg_data |= DRV_MSG_CODE_DIAG;
78             break;
79 
80         default:
81             DbgBreakMsg("invalid reason code.\n");
82             break;
83     }
84 
85     REG_WR_IND(
86         pdev,
87         pdev->hw_info.shmem_base +
88             OFFSETOF(shmem_region_t, drv_fw_mb.drv_mb),
89         msg_data);
90 
91     val = 0;
92 
93     /* wait for an acknowledgement. */
94     for(cnt = 0; cnt < fw_ack_timeout_us/5; cnt++)
95     {
96         mm_wait(pdev, 5);
97 
98         REG_RD_IND(
99             pdev,
100             pdev->hw_info.shmem_base +
101                 OFFSETOF(shmem_region_t, drv_fw_mb.fw_mb),
102             &val);
103         if((val & FW_MSG_ACK) == (msg_data & DRV_MSG_SEQ))
104         {
105             break;
106         }
107     }
108 
109     if((val & FW_MSG_ACK) != (msg_data & DRV_MSG_SEQ))
110     {
111         if((msg_data & DRV_MSG_DATA) != DRV_MSG_DATA_WAIT0)
112         {
113             msg_data &= ~DRV_MSG_CODE;
114             msg_data |= DRV_MSG_CODE_FW_TIMEOUT;
115 
116             REG_WR_IND(
117                 pdev,
118                 pdev->hw_info.shmem_base +
119                     OFFSETOF(shmem_region_t, drv_fw_mb.drv_mb),
120                 msg_data);
121 
122             pdev->vars.fw_timed_out = TRUE;
123             pdev->fw_timed_out_cnt++;
124 
125             DbgMessage(pdev, WARN, "firmware timed out.\n");
126         }
127 
128         return TRUE;
129     }
130 
131     return FALSE;
132 } /* fw_reset_sync */
133 
134 
135 
136 /*******************************************************************************
137  * Description:
138  *
139  * Return:
140  ******************************************************************************/
141 STATIC void
142 init_context_5706_a0_wa(
143     lm_device_t *pdev)
144 {
145     u8_t vcid_to_pcid[96];
146     u32_t vcid_addr;
147     u32_t pcid_addr;
148     u32_t offset;
149     u32_t vcid;
150 
151     /* In A0 silicon, certain context memory region is not accessible
152      * due to address decoding problem.  The bad context memory is identify
153      * by its pcid having Bit 3 set.  This table provides a mapping between
154      * the virtual context id to the usable physical context id. */
155     vcid_to_pcid[0x00] = 0x00; vcid_to_pcid[0x01] = 0x01;
156     vcid_to_pcid[0x02] = 0x02; vcid_to_pcid[0x03] = 0x03;
157     vcid_to_pcid[0x04] = 0x04; vcid_to_pcid[0x05] = 0x05;
158     vcid_to_pcid[0x06] = 0x06; vcid_to_pcid[0x07] = 0x07;
159     vcid_to_pcid[0x08] = 0x60; vcid_to_pcid[0x09] = 0x61;   /* bad entries. */
160     vcid_to_pcid[0x0a] = 0x62; vcid_to_pcid[0x0b] = 0x63;   /* bad entries. */
161     vcid_to_pcid[0x0c] = 0x64; vcid_to_pcid[0x0d] = 0x65;   /* bad entries. */
162     vcid_to_pcid[0x0e] = 0x66; vcid_to_pcid[0x0f] = 0x67;   /* bad entries. */
163     vcid_to_pcid[0x10] = 0x10; vcid_to_pcid[0x11] = 0x11;
164     vcid_to_pcid[0x12] = 0x12; vcid_to_pcid[0x13] = 0x13;
165     vcid_to_pcid[0x14] = 0x14; vcid_to_pcid[0x15] = 0x15;
166     vcid_to_pcid[0x16] = 0x16; vcid_to_pcid[0x17] = 0x17;
167     vcid_to_pcid[0x18] = 0x70; vcid_to_pcid[0x19] = 0x71;   /* bad entries. */
168     vcid_to_pcid[0x1a] = 0x72; vcid_to_pcid[0x1b] = 0x73;   /* bad entries. */
169     vcid_to_pcid[0x1c] = 0x74; vcid_to_pcid[0x1d] = 0x75;   /* bad entries. */
170     vcid_to_pcid[0x1e] = 0x76; vcid_to_pcid[0x1f] = 0x77;   /* bad entries. */
171     vcid_to_pcid[0x20] = 0x20; vcid_to_pcid[0x21] = 0x21;
172     vcid_to_pcid[0x22] = 0x22; vcid_to_pcid[0x23] = 0x23;
173     vcid_to_pcid[0x24] = 0x24; vcid_to_pcid[0x25] = 0x25;
174     vcid_to_pcid[0x26] = 0x26; vcid_to_pcid[0x27] = 0x27;
175     vcid_to_pcid[0x28] = 0x80; vcid_to_pcid[0x29] = 0x81;   /* bad entries. */
176     vcid_to_pcid[0x2a] = 0x82; vcid_to_pcid[0x2b] = 0x83;   /* bad entries. */
177     vcid_to_pcid[0x2c] = 0x84; vcid_to_pcid[0x2d] = 0x85;   /* bad entries. */
178     vcid_to_pcid[0x2e] = 0x86; vcid_to_pcid[0x2f] = 0x87;   /* bad entries. */
179     vcid_to_pcid[0x30] = 0x30; vcid_to_pcid[0x31] = 0x31;
180     vcid_to_pcid[0x32] = 0x32; vcid_to_pcid[0x33] = 0x33;
181     vcid_to_pcid[0x34] = 0x34; vcid_to_pcid[0x35] = 0x35;
182     vcid_to_pcid[0x36] = 0x36; vcid_to_pcid[0x37] = 0x37;
183     vcid_to_pcid[0x38] = 0x90; vcid_to_pcid[0x39] = 0x91;   /* bad entries. */
184     vcid_to_pcid[0x3a] = 0x92; vcid_to_pcid[0x3b] = 0x93;   /* bad entries. */
185     vcid_to_pcid[0x3c] = 0x94; vcid_to_pcid[0x3d] = 0x95;   /* bad entries. */
186     vcid_to_pcid[0x3e] = 0x96; vcid_to_pcid[0x3f] = 0x97;   /* bad entries. */
187     vcid_to_pcid[0x40] = 0x40; vcid_to_pcid[0x41] = 0x41;
188     vcid_to_pcid[0x42] = 0x42; vcid_to_pcid[0x43] = 0x43;
189     vcid_to_pcid[0x44] = 0x44; vcid_to_pcid[0x45] = 0x45;
190     vcid_to_pcid[0x46] = 0x46; vcid_to_pcid[0x47] = 0x47;
191     vcid_to_pcid[0x48] = 0xa0; vcid_to_pcid[0x49] = 0xa1;   /* bad entries. */
192     vcid_to_pcid[0x4a] = 0xa2; vcid_to_pcid[0x4b] = 0xa3;   /* bad entries. */
193     vcid_to_pcid[0x4c] = 0xa4; vcid_to_pcid[0x4d] = 0xa5;   /* bad entries. */
194     vcid_to_pcid[0x4e] = 0xa6; vcid_to_pcid[0x4f] = 0xa7;   /* bad entries. */
195     vcid_to_pcid[0x50] = 0x50; vcid_to_pcid[0x51] = 0x51;
196     vcid_to_pcid[0x52] = 0x52; vcid_to_pcid[0x53] = 0x53;
197     vcid_to_pcid[0x54] = 0x54; vcid_to_pcid[0x55] = 0x55;
198     vcid_to_pcid[0x56] = 0x56; vcid_to_pcid[0x57] = 0x57;
199     vcid_to_pcid[0x58] = 0xb0; vcid_to_pcid[0x59] = 0xb1;   /* bad entries. */
200     vcid_to_pcid[0x5a] = 0xb2; vcid_to_pcid[0x5b] = 0xb3;   /* bad entries. */
201     vcid_to_pcid[0x5c] = 0xb4; vcid_to_pcid[0x5d] = 0xb5;   /* bad entries. */
202     vcid_to_pcid[0x5e] = 0xb6; vcid_to_pcid[0x5f] = 0xb7;   /* bad entries. */
203 
204     vcid = sizeof(vcid_to_pcid);
205     while(vcid)
206     {
207         vcid--;
208 
209         vcid_addr = GET_PCID_ADDR(vcid);
210         pcid_addr = GET_PCID_ADDR(vcid_to_pcid[vcid]);
211 
212         /* There maybe some residuals in the context that may cause
213          * receive problem later.  The problem intermittently occurs
214          * when we are resetting the chip while there are incoming
215          * traffic and some other firmware is running.  To prevent this
216          * problem from occuring we need to zero out context first
217          * before initializing the virtual to physical mapping.  We
218          * arbitrarily use a virtual context address 0x00 to map to a
219          * physical context one at a time then zero them out.
220          *
221          * First map the physical context to virtual context 0 then
222          * zero out the context. */
223         REG_WR(pdev, context.ctx_virt_addr, 0x00);
224         REG_WR(pdev, context.ctx_page_tbl, pcid_addr);
225 
226         /* Zero out the context. */
227         for(offset = 0; offset < PHY_CTX_SIZE; offset += 4)
228         {
229             CTX_WR(pdev, 0x00, offset, 0);
230         }
231 
232         /* Now initalize the correct mapping in which the virtual
233          * context to the correspondinding physical context. */
234         REG_WR(pdev, context.ctx_virt_addr, vcid_addr);
235         REG_WR(pdev, context.ctx_page_tbl, pcid_addr);
236     }
237 } /* init_context_5706_a0_wa */
238 
239 
240 
241 /*******************************************************************************
242  * Description:
243  *
244  * Return:
245  ******************************************************************************/
246 STATIC void
247 init_context_5706(
248     lm_device_t *pdev)
249 {
250     u32_t vcid_addr;
251     u32_t offset;
252 
253     vcid_addr = GET_CID_ADDR(96);   /* This corresponds to 48 context. */
254 
255     while(vcid_addr)
256     {
257         vcid_addr -= PHY_CTX_SIZE;
258 
259         /* There maybe some residuals in the context that may cause
260          * receive problem later.  The problem intermittently occurs
261          * when we are resetting the chip while there are incoming
262          * traffic and some other firmware is running.  To prevent this
263          * problem from occuring we need to zero out context first
264          * before initializing the virtual to physical mapping.  We
265          * arbitrarily use a virtual context address 0x00 to map to a
266          * physical context one at a time then zero them out.
267          *
268          * First map the physical context to virtual context 0 then
269          * zero out the context. */
270         REG_WR(pdev, context.ctx_virt_addr, 0x00);
271         REG_WR(pdev, context.ctx_page_tbl, vcid_addr);
272 
273         /* Zero out the context. */
274         for(offset = 0; offset < PHY_CTX_SIZE; offset += 4)
275         {
276             CTX_WR(pdev, 0x00, offset, 0);
277         }
278 
279         /* Now initalize the correct mapping in which the virtual
280          * context to the correspondinding physical context. */
281         REG_WR(pdev, context.ctx_virt_addr, vcid_addr);
282         REG_WR(pdev, context.ctx_page_tbl, vcid_addr);
283     }
284 } /* init_context_5706 */
285 
286 
287 
288 /*******************************************************************************
289  * Description:
290  *
291  * Return:
292  ******************************************************************************/
293 STATIC void
294 init_context_5709(
295     lm_device_t *pdev)
296 {
297     lm_address_t mem_phy;
298     u8_t *mem_virt;
299     u32_t mem_size;
300     u32_t page_idx;
301     u32_t idx;
302     u32_t cnt;
303     u32_t val;
304 
305     DbgBreakIf(CHIP_NUM(pdev) != CHIP_NUM_5709);
306 
307     val = 0x3001;
308     val |= (LM_PAGE_BITS - 8) << 16;
309     REG_WR(pdev, context.ctx_command, val);
310 
311     page_idx = 0;
312 
313     for(idx = 0; idx < NUM_CTX_MBLKS; idx++)
314     {
315         mem_virt = pdev->vars.ctx_mem[idx].start;
316         mem_phy = pdev->vars.ctx_mem[idx].start_phy;
317         mem_size = pdev->vars.ctx_mem[idx].size;
318 
319         DbgBreakIf(mem_phy.as_u32.low & LM_PAGE_MASK);
320         DbgBreakIf(mem_size & LM_PAGE_MASK);
321 
322         while(mem_size)
323         {
324             for(cnt = 0; cnt < LM_PAGE_SIZE; cnt += 4)
325             {
326                 ((u32_t *) mem_virt)[cnt/4] = 0;
327             }
328 
329             REG_WR(
330                 pdev,
331                 context.ctx_host_page_tbl_data0,
332                 mem_phy.as_u32.low | CTX_HOST_PAGE_TBL_DATA0_VALID);
333             REG_WR(
334                 pdev,
335                 context.ctx_host_page_tbl_data1,
336                 mem_phy.as_u32.high);
337             REG_WR(
338                 pdev,
339                 context.ctx_host_page_tbl_ctrl,
340                 page_idx | CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
341 
342             for(cnt = 0; cnt < 100; cnt++)
343             {
344                 REG_RD(pdev, context.ctx_host_page_tbl_ctrl, &val);
345 
346                 if(!(val & CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ))
347                 {
348                     break;
349                 }
350 
351                 mm_wait(pdev, 5);
352             }
353 
354             DbgBreakIf(val & CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
355 
356             mem_virt += LM_PAGE_SIZE;
357             LM_INC64(&mem_phy, LM_PAGE_SIZE);
358             mem_size -= LM_PAGE_SIZE;
359 
360             page_idx++;
361         }
362     }
363 } /* init_context_5709 */
364 
365 
366 
367 /*******************************************************************************
368  * Description:
369  *    This workaround must be applied right after a CORE clock reset
370  *    and before enable other blocks which may try to allocate mbufs.
371  *
372  * Return:
373  ******************************************************************************/
374 STATIC void
375 alloc_bad_rbuf_5706_a0_wa(
376     lm_device_t *pdev)
377 {
378     u16_t good_mbuf[512];
379     u32_t good_mbuf_cnt;
380     u32_t val;
381 
382     REG_WR(
383         pdev,
384         misc.misc_enable_set_bits,
385         MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE);
386 
387     good_mbuf_cnt = 0;
388 
389     /* Allocate a bunch of mbufs and save the good ones in an array. */
390     REG_RD_IND(pdev, OFFSETOF(reg_space_t, rbuf.rbuf_status1), &val);
391     while(val & RBUF_STATUS1_FREE_COUNT)
392     {
393         REG_WR_IND(
394             pdev,
395             OFFSETOF(reg_space_t, rbuf.rbuf_command),
396             RBUF_COMMAND_ALLOC_REQ_TE);
397 
398         REG_RD_IND(
399             pdev,
400             OFFSETOF(reg_space_t, rbuf.rbuf_fw_buf_alloc),
401             &val);
402         val &= RBUF_FW_BUF_ALLOC_VALUE;
403 
404         /* The addresses with Bit 9 set are bad memory blocks. */
405         if(!(val & (1 << 9)))
406         {
407             DbgBreakIf(good_mbuf_cnt >= sizeof(good_mbuf)/sizeof(u16_t));
408 
409             good_mbuf[good_mbuf_cnt] = (u16_t) val;
410             good_mbuf_cnt++;
411         }
412 
413         REG_RD_IND(pdev, OFFSETOF(reg_space_t, rbuf.rbuf_status1), &val);
414     }
415 
416     /* Free the good ones back to the mbuf pool thus discardining
417      * all the bad ones. */
418     while(good_mbuf_cnt)
419     {
420         good_mbuf_cnt--;
421 
422         val = good_mbuf[good_mbuf_cnt];
423         val = (val << 9) | val | 1;
424 
425         REG_WR_IND(pdev, OFFSETOF(reg_space_t, rbuf.rbuf_fw_buf_free), val);
426     }
427 } /* alloc_bad_rbuf_5706_a0_wa */
428 
429 
430 
431 /*******************************************************************************
432  * Description:
433  *
434  * Return:
435  ******************************************************************************/
436 void
437 lm_chip_reset(
438     lm_device_t *pdev,
439     lm_reason_t reason)
440 {
441     u32_t val;
442     u32_t idx;
443 
444     DbgMessage(pdev, VERBOSE, "+++ lm_chip_reset\n");
445     pdev->chip_reset_cnt++;
446 
447     /* acquiesce the bus before a reset. */
448     if(CHIP_NUM(pdev) == CHIP_NUM_5706 || CHIP_NUM(pdev) == CHIP_NUM_5708)
449     {
450         REG_WR(
451             pdev,
452             misc.misc_enable_clr_bits,
453             MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
454                 MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
455                 MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE);
456         mm_wait(pdev, 5);
457     }
458     else
459     {
460         if(CHIP_ID(pdev) == CHIP_ID_5709_A0)
461         {
462             /* Disable bus_master. */
463             REG_RD_OFFSET(
464                 pdev,
465                 OFFSETOF(reg_space_t, pci_config.pcicfg_command),
466                 &val);
467             val &= ~PCICFG_COMMAND_BUS_MASTER;
468             REG_WR_OFFSET(
469                 pdev,
470                 OFFSETOF(reg_space_t, pci_config.pcicfg_command),
471                 val);
472         }
473         else
474         {
475             /* Disable DMA activities. */
476             REG_RD(pdev, misc.misc_new_core_ctl, &val);
477             val &= ~(1 << 16);
478             REG_WR(pdev, misc.misc_new_core_ctl, val);
479         }
480 
481         /* wait until there is no pending transaction. */
482         for(idx = 0; idx < 1000; idx++)
483         {
484             REG_RD_OFFSET(
485                 pdev,
486                 OFFSETOF(reg_space_t, pci_config.pcicfg_device_control),
487                 &val);
488             if((val & (PCICFG_DEVICE_STATUS_NO_PEND << 16)) == 0)
489             {
490                 break;
491             }
492 
493             mm_wait(pdev, 5);
494         }
495     }
496 
497     /* Enable or disable remote phy. */
498     REG_RD_IND(
499         pdev,
500         pdev->hw_info.shmem_base +
501             OFFSETOF(shmem_region_t, drv_fw_cap_mb.fw_cap_mb),
502         &val);
503 
504     if((val & CAPABILITY_SIGNATURE_MASK) == FW_CAP_SIGNATURE)
505     {
506         val = DRV_ACK_CAP_SIGNATURE;
507 
508         if(pdev->params.enable_remote_phy)
509         {
510             if (LM_REASON_DIAG != reason)
511             {
512                 val |= FW_CAP_REMOTE_PHY_CAPABLE;
513             }
514             else
515             {
516                 val &= ~FW_CAP_REMOTE_PHY_CAPABLE;
517             }
518         }
519 
520         REG_WR_IND(
521             pdev,
522             pdev->hw_info.shmem_base +
523                 OFFSETOF(shmem_region_t, drv_fw_cap_mb.drv_ack_cap_mb),
524             val);
525     }
526 
527     /* Wait for the firmware to tell us it is ok to issue a reason. */
528     (void) fw_reset_sync(pdev, reason, DRV_MSG_DATA_WAIT0, FW_ACK_TIME_OUT_MS*1000);
529 
530     /* Deposit a driver reset signature so the firmware knows
531      * that this is a soft reset. */
532     REG_WR_IND(
533         pdev,
534         pdev->hw_info.shmem_base +
535             OFFSETOF(shmem_region_t, drv_fw_mb.drv_reset_signature),
536         DRV_RESET_SIGNATURE);
537 
538     /* Force the driver to wait for the acknowledgement from
539      * the firmware. */
540     pdev->vars.fw_timed_out = FALSE;
541 
542     /* Do a dummy read to force the chip to complete all current
543      * transaction before we issue a reset.  This is a workaround
544      * for A0.  If there is any pending transactions when a reset
545      * occur, the chip will lock up.  There must be one last read
546      * before a core clock reset. */
547     REG_RD(pdev, misc.misc_id, &val);
548 
549     /* Chip reset. */
550     if(CHIP_NUM(pdev) == CHIP_NUM_5706 || CHIP_NUM(pdev) == CHIP_NUM_5708)
551     {
552         REG_WR(
553             pdev,
554             pci_config.pcicfg_misc_config,
555             PCICFG_MISC_CONFIG_CORE_RST_REQ |
556                 PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
557                 PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP);
558 
559         /* Wait for the firmware to configure for PLL bypass.  This is a
560          * 5706 A0 workaround.  Without the wait the system will lock up
561          * on the first register access in PCI-X mode and may intermittently
562          * do the same in PCI mode. */
563         if(CHIP_ID(pdev) == CHIP_ID_5706_A0 || CHIP_ID(pdev) == CHIP_ID_5706_A1)
564         {
565             /* 15ms is how long for the first stage of bootcode to load
566              * and set up the PLL bypass. */
567             for(idx = 0; idx < 1000; idx++)
568             {
569                 mm_wait(pdev, 15);
570             }
571         }
572 
573         /* Reset takes at approximate 3ms on the FPGA which is 100 times
574          * slower than the real chip.  IKOS is 10 times slower than the FPGA. */
575         for(idx = 0; idx < 5000; idx++)
576         {
577             REG_RD(pdev, pci_config.pcicfg_misc_config, &val);
578 
579             mm_wait(pdev, 10);
580 
581             if((val & (
582                 PCICFG_MISC_CONFIG_CORE_RST_REQ |
583                 PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0)
584             {
585                 break;
586             }
587         }
588 
589         DbgBreakIf(val & (
590             PCICFG_MISC_CONFIG_CORE_RST_REQ |
591             PCICFG_MISC_CONFIG_CORE_RST_BSY));
592     }
593     else
594     {
595         REG_WR(pdev, misc.misc_command, MISC_COMMAND_SW_RESET);
596 
597         /* Flush the previous write and wait at least 500 nsec */
598         REG_RD( pdev, misc.misc_command, &val);
599         mm_wait(pdev, 1);
600 
601         /* Reset takes at approximate 3ms on the FPGA which is 100 times
602          * slower than the real chip.  IKOS is 10 times slower than the FPGA. */
603         for(idx = 0; idx < 5000; idx++)
604         {
605             REG_RD(pdev, misc.misc_command, &val);
606 
607             mm_wait(pdev, 10);
608 
609             if((val & MISC_COMMAND_SW_RESET) == 0)
610             {
611                 break;
612             }
613         }
614 
615         DbgBreakIf(val & MISC_COMMAND_SW_RESET);
616 
617         REG_WR(
618             pdev,
619             pci_config.pcicfg_misc_config,
620             PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
621                 PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP);
622 
623         if(CHIP_ID(pdev) == CHIP_ID_5709_A0)
624         {
625             REG_RD_OFFSET(
626                 pdev,
627                 OFFSETOF(reg_space_t, pci_config.pcicfg_command),
628                 &val);
629             val |= PCICFG_COMMAND_BUS_MASTER;
630             REG_WR_OFFSET(
631                 pdev,
632                 OFFSETOF(reg_space_t, pci_config.pcicfg_command),
633                 val);
634 
635             /* cq#28345. */
636             REG_RD(pdev, tsch.tsch_ctx_access_cfg, &val);
637             val &= ~TSCH_CTX_ACCESS_CFG_L5_TCMD_PREFETCH_SIZE;
638             REG_WR(pdev, tsch.tsch_ctx_access_cfg, val);
639         }
640         else
641         {
642             if((reason == LM_REASON_DRIVER_RESET) || (reason == LM_REASON_DIAG))
643             {
644                 /* Enable DMA activities. */
645                 REG_RD(pdev, misc.misc_new_core_ctl, &val);
646                 val |= (1 << 16);
647                 REG_WR(pdev, misc.misc_new_core_ctl, val);
648             }
649         }
650 
651         if(CHIP_ID(pdev) == CHIP_ID_5709_A0 ||
652             CHIP_ID(pdev) == CHIP_ID_5709_B0 ||
653             CHIP_ID(pdev) == CHIP_ID_5709_B1 ||
654             CHIP_ID(pdev) == CHIP_ID_5709_B2 ||
655             CHIP_ID(pdev) == CHIP_ID_5709_A1)
656         {
657             REG_RD(pdev, mq.mq_config, &val);
658             REG_WR(pdev, mq.mq_config, val | MQ_CONFIG_HALT_DIS);
659         }
660     }
661 
662     DbgMessage1(pdev, INFORM, "Reset done, idx = %d\n", idx);
663 
664     /* Wait for the firmware to finish its initialization. */
665     (void) fw_reset_sync(pdev, reason, DRV_MSG_DATA_WAIT1, FW_ACK_TIME_OUT_MS*1000);
666 
667     /* Make sure byte swapping is properly configured. */
668     REG_RD(pdev, pci.pci_swap_diag0, &val);
669 
670     DbgBreakIf(val != 0x01020304);
671 
672     /* The emac block will lock up if the power_down_mode is enabled.
673      *
674      * This is now done by the bootcode.
675      *
676      * lm_mread(pdev, PHY_CTRL_REG, &val);
677      * if(val & PHY_CTRL_LOWER_POWER_MODE)
678      * {
679      *    val &= ~PHY_CTRL_LOWER_POWER_MODE;
680      *    lm_mwrite(pdev, PHY_CTRL_REG, val);
681      * } */
682 
683     if(CHIP_NUM(pdev) == CHIP_NUM_5709)
684     {
685         /* make sure the MSI-X setting is preserved */
686         REG_WR(pdev,
687                pci.pci_grc_window_addr,
688                (pdev->hw_info.shmem_base & ~0x7fff) |
689                 PCI_GRC_WINDOW_ADDR_SEP_WIN);
690 
691         REG_WR(pdev,
692                pci.pci_grc_window1_addr,
693                (pdev->hw_info.shmem_base & ~0x7fff) + 0x6000 /*0x16e000 */);
694 
695         REG_WR(pdev,
696                pci.pci_grc_window2_addr,
697                MSIX_TABLE_ADDR /*MSIX vector addr */);
698         REG_WR(pdev,
699                pci.pci_grc_window3_addr,
700                MSIX_PBA_ADDR /*MSIX PBA addr */);
701         REG_WR(pdev, pci.pci_msix_tbl_off_bir, PCI_GRC_WINDOW2_BASE);
702         REG_WR(pdev, pci.pci_msix_pba_off_bit, PCI_GRC_WINDOW3_BASE);
703         if(pdev->params.ena_large_grc_timeout)
704         {
705             /* this workaround cause IBM minnow to reboot randomly */
706             /* set large GRC timeout in MSIX mode */
707             REG_RD(pdev, misc.misc_eco_hw_ctl, &val);
708             val |= MISC_ECO_HW_CTL_LARGE_GRC_TMOUT_EN;
709             REG_WR(pdev, misc.misc_eco_hw_ctl, val);
710         }
711         else
712         {
713             REG_RD(pdev, misc.misc_eco_hw_ctl, &val);
714             val &= ~MISC_ECO_HW_CTL_LARGE_GRC_TMOUT_EN;
715             REG_WR(pdev, misc.misc_eco_hw_ctl, val);
716         }
717     }
718     else
719     {
720         /* Default 32k window. */
721         REG_WR(pdev, pci.pci_grc_window_addr, pdev->hw_info.shmem_base & ~0x7fff);
722     }
723 
724     /* 5706A0 workaround. */
725     if(CHIP_ID(pdev) == CHIP_ID_5706_A0)
726     {
727         /* Adjust the voltage regular to two steps lower.  The default
728          * of this register is 0x0000000e. */
729         REG_WR(pdev, misc.misc_vreg_control, 0x000000fa);
730 
731         /* Remove bad rbuf memory from the free pool. */
732         alloc_bad_rbuf_5706_a0_wa(pdev);
733     }
734 
735     REG_WR(
736         pdev,
737         timer.timer_sw_tmr_reload_value1,
738         pdev->params.tmr_reload_value1);
739 
740     (void) lm_set_mac_addr(pdev, 0x0, pdev->params.mac_addr);
741 
742     val = pdev->params.mac_addr[0] +
743         (pdev->params.mac_addr[1] << 8) +
744         (pdev->params.mac_addr[2] << 16) +
745         pdev->params.mac_addr[3] +
746         (pdev->params.mac_addr[4] << 8) +
747         (pdev->params.mac_addr[5] << 16);
748     REG_WR(pdev, emac.emac_backoff_seed, val);
749 
750     (void) lm_set_rx_mask(
751         pdev,
752         RX_FILTER_USER_IDX0,
753         pdev->rx_info.mask[RX_FILTER_USER_IDX0]);
754 
755     /* The firmware relies on the driver to issue a periodic pulse to
756      * determine when to go enter an OS absent mode.  During debugging
757      * we may not want the firmware to go into this mode. */
758     if(pdev->params.test_mode & TEST_MODE_DRIVER_PULSE_ALWAYS_ALIVE)
759     {
760         pdev->vars.drv_pulse_wr_seq++;
761 
762         val = pdev->vars.drv_pulse_wr_seq | DRV_PULSE_ALWAYS_ALIVE;
763 
764         REG_WR_IND(
765             pdev,
766             pdev->hw_info.shmem_base +
767                 OFFSETOF(shmem_region_t, drv_fw_mb.drv_pulse_mb),
768             val);
769     }
770 } /* lm_chip_reset */
771 
772 
773 
774 /*******************************************************************************
775  * Description:
776  *
777  * Return:
778  ******************************************************************************/
779 void
780 lm_setup_bd_chain_ring(
781     u8_t *mem_virt,
782     lm_address_t mem_phy,
783     u32_t page_cnt)
784 {
785     lm_address_t start_mem_phy;
786     u8_t *start_mem_virt;
787     tx_bd_next_t *next_ptr;
788     u32_t idx;
789 
790     DbgBreakIf(
791         ((u32_t) PTR_SUB(mem_virt, 0) & LM_PAGE_MASK) !=
792             (mem_phy.as_u32.low & LM_PAGE_MASK));
793 
794     start_mem_phy = mem_phy;
795     start_mem_virt = mem_virt;
796 
797     for(idx = 0; idx < page_cnt-1; idx++)
798     {
799         /* Increment mem_phy to the next page. */
800         LM_INC64(&mem_phy, LM_PAGE_SIZE);
801 
802         next_ptr = &((tx_bd_next_t *) mem_virt)[MAX_BD_PER_PAGE];
803 
804         /* Initialize the physical address of the next bd chain. */
805         next_ptr->tx_bd_next_paddr_hi = mem_phy.as_u32.high;
806         next_ptr->tx_bd_next_paddr_lo = mem_phy.as_u32.low;
807 
808         /* Initialize the virtual address of the next bd chain. */
809         *((u8_t **) next_ptr->tx_bd_next_reserved) = mem_virt + LM_PAGE_SIZE;
810 
811         /* Move to the next bd chain. */
812         mem_virt += LM_PAGE_SIZE;
813     }
814 
815     next_ptr = &((tx_bd_next_t *) mem_virt)[MAX_BD_PER_PAGE];
816 
817     next_ptr->tx_bd_next_paddr_hi = start_mem_phy.as_u32.high;
818     next_ptr->tx_bd_next_paddr_lo = start_mem_phy.as_u32.low;
819     *((u8_t **) next_ptr->tx_bd_next_reserved) = start_mem_virt;
820 } /* lm_setup_bd_chain_ring */
821 
822 
823 
824 #ifndef EXCLUDE_KQE_SUPPORT
825 /*******************************************************************************
826  * Description:
827  *
828  * Return:
829  ******************************************************************************/
830 STATIC void
831 setup_page_table(
832     void *page_table,
833     u32_t page_cnt,
834     lm_address_t page_base_phy)
835 {
836     u32_t *page_entry;
837 
838     page_entry = (u32_t *) page_table;
839     while(page_cnt)
840     {
841         /* Each entry needs to be in big endian format. */
842         *page_entry = page_base_phy.as_u32.high;
843         page_entry++;
844         *page_entry = page_base_phy.as_u32.low;
845         page_entry++;
846 
847         LM_INC64(&page_base_phy, LM_PAGE_SIZE);
848 
849         page_cnt--;
850     }
851 } /* setup_page_table */
852 #endif
853 
854 
855 #if INCLUDE_OFLD_SUPPORT
856 /*******************************************************************************
857  * Description:
858  *
859  * Return:
860  ******************************************************************************/
861 STATIC void
862 l4_reset_setup(
863     lm_device_t *pdev)
864 {
865     u32_t val;
866 
867     lm_setup_bd_chain_ring(
868         (u8_t *) pdev->ofld.gen_chain.bd_chain_virt,
869         pdev->ofld.gen_chain.bd_chain_phy,
870         pdev->params.gen_bd_page_cnt);
871 
872     pdev->ofld.gen_chain.prod_idx = 0;
873     pdev->ofld.gen_chain.prod_bseq = 0;
874     pdev->ofld.gen_chain.prod_bd = pdev->ofld.gen_chain.bd_chain_virt;
875 
876     /* Don't count the last bd of a BD page.  A full BD chain must
877      * have at least one empty entry. */
878     pdev->ofld.gen_chain.bd_left =  pdev->params.gen_bd_page_cnt *
879         MAX_BD_PER_PAGE - 1;
880 
881     DbgMessage2(pdev, INFORMrs, "gen_chain %p, bd_left %d\n",
882         pdev->ofld.gen_chain.bd_chain_virt,
883         pdev->ofld.gen_chain.bd_left);
884 
885     /* Initialize the type, size, bd_pre_read. */
886     val = L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE << 24;
887     val |= (((sizeof(l2_bd_chain_context_t) + 0x1f) & ~0x1f) / 0x20) << 16;
888     val |= 0x2 << 8;
889     CTX_WR(
890         pdev,
891         pdev->ofld.gen_chain.cid_addr,
892         WORD_ALIGNED_OFFSETOF(l2_bd_chain_context_t, l2ctx_ctx_type),
893         val);
894 
895     val = pdev->ofld.gen_chain.bd_chain_phy.as_u32.high;
896     CTX_WR(
897         pdev,
898         pdev->ofld.gen_chain.cid_addr,
899         WORD_ALIGNED_OFFSETOF(l2_bd_chain_context_t, l2ctx_nx_bdhaddr_hi),
900         val);
901 
902     val = pdev->ofld.gen_chain.bd_chain_phy.as_u32.low;
903     CTX_WR(
904         pdev,
905         pdev->ofld.gen_chain.cid_addr,
906         WORD_ALIGNED_OFFSETOF(l2_bd_chain_context_t, l2ctx_nx_bdhaddr_lo),
907         val);
908 
909     /* Set up the hcopy chain. */
910     if(pdev->params.hcopy_desc_cnt)
911     {
912         lm_setup_bd_chain_ring(
913             (u8_t *) pdev->ofld.hcopy_chain.bd_chain_virt,
914             pdev->ofld.hcopy_chain.bd_chain_phy,
915             pdev->params.hcopy_bd_page_cnt);
916 
917         pdev->ofld.hcopy_chain.prod_bd =
918             pdev->ofld.hcopy_chain.bd_chain_virt;
919         pdev->ofld.hcopy_chain.prod_idx = 0;
920         pdev->ofld.hcopy_chain.con_idx = 0;
921         pdev->ofld.hcopy_chain.prod_bseq = 0;
922 
923         /* Don't count the last bd of a BD page.  A full BD chain must
924          * have at least one empty entry. */
925         pdev->ofld.hcopy_chain.bd_left = pdev->params.hcopy_bd_page_cnt *
926             MAX_BD_PER_PAGE - 1;
927 
928         val = L4CTX_TYPE_TYPE_L2 << 24;
929         val |= (((sizeof(l4_context_t) + 0x1f) & ~0x1f) / 0x20) << 16;
930         CTX_WR(
931             pdev,
932             pdev->ofld.hcopy_chain.cid_addr,
933             WORD_ALIGNED_OFFSETOF(l4_context_t, l4ctx_ctx_type),
934             val);
935 
936         val = (CCELL_CMD_TYPE_TYPE_L2 | ((LM_PAGE_BITS-8) << 4)) << 24;
937         val |= 8 << 16;
938         CTX_WR(
939             pdev,
940             pdev->ofld.hcopy_chain.cid_addr,
941             WORD_ALIGNED_OFFSETOF(l4_context_t, l4ctx_cmd),
942             val);
943 
944         val = pdev->ofld.hcopy_chain.bd_chain_phy.as_u32.high;
945         CTX_WR(
946             pdev,
947             pdev->ofld.hcopy_chain.cid_addr,
948             WORD_ALIGNED_OFFSETOF(l4_context_t, l4ctx_cmd) +
949             WORD_ALIGNED_OFFSETOF(tcp_context_cmd_cell_te_t,
950                 ccell_tbdr_bhaddr.hi),
951             val);
952 
953         val = pdev->ofld.hcopy_chain.bd_chain_phy.as_u32.low;
954         CTX_WR(
955             pdev,
956             pdev->ofld.hcopy_chain.cid_addr,
957             WORD_ALIGNED_OFFSETOF(l4_context_t, l4ctx_cmd) +
958             WORD_ALIGNED_OFFSETOF(tcp_context_cmd_cell_te_t,
959                 ccell_tbdr_bhaddr.lo),
960             val);
961     }
962 
963     /* Setup statistics mapping. */
964     REG_WR(
965         pdev,
966         hc.hc_stat_gen_sel_0,
967         HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT0_TE |             /* 0 - inseg */
968             (HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT1_TE << 8) |  /* 1 - inerr */
969             (HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT2_TE << 16) | /* 2 - inrecv */
970             (HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT3_TE << 24)); /* 3 - inhdrerr */
971 
972     REG_WR(
973         pdev,
974         hc.hc_stat_gen_sel_1,
975         HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT4_TE |             /* 4 - indiscard */
976             (HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT5_TE << 8) |  /* 5 - indeliver */
977             (HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT0_TE << 16) | /* 6 - outseg */
978             (HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT1_TE << 24)); /* 7 - retrans */
979 
980     REG_WR(
981         pdev,
982         hc.hc_stat_gen_sel_2,
983         HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT2_TE |             /* 8 - outreset */
984             (HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT3_TE << 8) |  /* 9 - outreq */
985             (HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT4_TE << 16) | /* 10 - outdiscrd */
986             (HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT5_TE << 24)); /* 11 - outnorte */
987 
988     /* set enable_iscsi_fast_response. */
989     REG_WR_IND(
990             pdev,
991             OFFSETOF(reg_space_t, com.com_scratch[0])+COM_HSI_OFFSETOFF(enable_fast_iscsi_response),
992             pdev->params.enable_fir);
993 } /* l4_reset_setup */
994 #endif
995 
996 
997 
998 /*******************************************************************************
999  * Description:
1000  *
1001  * Return:
1002  ******************************************************************************/
1003 STATIC void
1004 init_l2txq(
1005     lm_device_t *pdev)
1006 {
1007     lm_tx_chain_t *txq;
1008     u32_t bd_page_cnt;
1009     u32_t offset;
1010     u32_t idx;
1011     u32_t val;
1012 
1013     for(idx = 0; idx < sizeof(lm_tx_stats_t)/sizeof(u32_t); idx++)
1014     {
1015         ((u32_t *) &pdev->tx_info.stats)[idx] = 0;
1016     }
1017 
1018     for(idx = 0; idx < pdev->tx_info.num_txq; idx++)
1019     {
1020         txq = &pdev->tx_info.chain[idx];
1021 
1022         bd_page_cnt = pdev->params.l2_tx_bd_page_cnt[txq->idx];
1023 
1024         txq->prod_idx = 0;
1025         txq->con_idx = 0;
1026         txq->prod_bseq = 0;
1027         txq->prod_bd = txq->bd_chain_virt;
1028         txq->bd_left = bd_page_cnt * MAX_BD_PER_PAGE - 1;
1029 
1030         if(bd_page_cnt == 0)
1031         {
1032             continue;
1033         }
1034 
1035         lm_setup_bd_chain_ring(
1036             (u8_t *) txq->bd_chain_virt,
1037             txq->bd_chain_phy,
1038             bd_page_cnt);
1039 
1040 #ifndef L2_ONLY
1041         val = (L4CTX_TYPE_TYPE_L2 << 24) |
1042               (((sizeof(l4_context_t) + 0x1f) & ~0x1f) / 0x20) << 16;
1043 #else
1044         // This is equivalent as above, but some constants/structures are not
1045         // defined for Solaris
1046         val = (0x10 << 24) |
1047               (((80 * sizeof(u32_t) + 0x1f) & ~0x1f) / 0x20) << 16;
1048 #endif
1049 
1050         if (CHIP_NUM(pdev) == CHIP_NUM_5709)
1051         {
1052             offset = 0x80;
1053         }
1054         else
1055         {
1056             // offset = WORD_ALIGNED_OFFSETOF(l4_context_t, l4ctx_ctx_type);
1057             offset = 0;
1058         }
1059 
1060         CTX_WR(pdev, txq->cid_addr, offset, val);
1061 
1062         if (CHIP_NUM(pdev) == CHIP_NUM_5709)
1063         {
1064             offset = 0x240;
1065         }
1066         else
1067         {
1068             // offset = WORD_ALIGNED_OFFSETOF(l4_context_t, l4ctx_cmd);
1069             offset = 34*sizeof(u32_t);
1070         }
1071 
1072         val = (CCELL_CMD_TYPE_TYPE_L2 | ((LM_PAGE_BITS-8) << 4)) << 24;
1073         val |= 8 << 16;
1074         CTX_WR(pdev, txq->cid_addr, offset, val);
1075 
1076         val = txq->bd_chain_phy.as_u32.high;
1077         CTX_WR(
1078             pdev,
1079             txq->cid_addr,
1080             offset + WORD_ALIGNED_OFFSETOF(
1081                 tcp_context_cmd_cell_te_t, ccell_tbdr_bhaddr.hi),
1082             val);
1083 
1084         val = txq->bd_chain_phy.as_u32.low;
1085         CTX_WR(
1086             pdev,
1087             txq->cid_addr,
1088             offset + WORD_ALIGNED_OFFSETOF(
1089                 tcp_context_cmd_cell_te_t, ccell_tbdr_bhaddr.lo),
1090             val);
1091 
1092     }
1093 } /* init_l2txq */
1094 
1095 
1096 
1097 /*******************************************************************************
1098  * Description:
1099  *
1100  * Return:
1101  ******************************************************************************/
1102 STATIC void
1103 init_l2rxq(
1104     lm_device_t *pdev)
1105 {
1106     lm_rx_chain_t *rxq;
1107     u32_t bd_page_cnt;
1108     u32_t idx;
1109     u32_t val;
1110 
1111     for(idx = 0; idx < sizeof(lm_rx_stats_t)/sizeof(u32_t); idx++)
1112     {
1113         ((u32_t *) &pdev->rx_info.stats)[idx] = 0;
1114     }
1115 
1116     for(idx = 0; idx < pdev->rx_info.num_rxq; idx++)
1117     {
1118         rxq = &pdev->rx_info.chain[idx];
1119 
1120         bd_page_cnt = pdev->params.l2_rx_bd_page_cnt[rxq->idx];
1121 
1122         rxq->prod_idx = 0;
1123         rxq->con_idx = 0;
1124         rxq->prod_bseq = 0;
1125         rxq->prod_bd = rxq->bd_chain_virt;
1126         rxq->bd_left = bd_page_cnt * MAX_BD_PER_PAGE - 1;
1127 
1128         if(bd_page_cnt == 0)
1129         {
1130             continue;
1131         }
1132 
1133         lm_setup_bd_chain_ring(
1134             (u8_t *) rxq->bd_chain_virt,
1135             rxq->bd_chain_phy,
1136             bd_page_cnt);
1137 
1138         val = L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE << 24;
1139         val |= (((sizeof(l2_bd_chain_context_t) + 0x1f) & ~0x1f) / 0x20) << 16;
1140         val |= 0x02 << 8;
1141         CTX_WR(
1142             pdev,
1143             rxq->cid_addr,
1144             WORD_ALIGNED_OFFSETOF(l2_bd_chain_context_t, l2ctx_ctx_type),
1145             val);
1146 
1147         val = rxq->bd_chain_phy.as_u32.high;
1148         CTX_WR(
1149             pdev,
1150             rxq->cid_addr,
1151             WORD_ALIGNED_OFFSETOF(l2_bd_chain_context_t, l2ctx_nx_bdhaddr_hi),
1152             val);
1153 
1154         val = rxq->bd_chain_phy.as_u32.low;
1155         CTX_WR(
1156             pdev,
1157             rxq->cid_addr,
1158             WORD_ALIGNED_OFFSETOF(l2_bd_chain_context_t, l2ctx_nx_bdhaddr_lo),
1159             val);
1160 
1161         //  In case we are coming out from hibernation, we need to restore
1162         //  previous MTU setting. Otherwise, we would initialize max packet
1163         //  length to default (i.e. initial power-up)
1164         CTX_WR(
1165             pdev,
1166             rxq->cid_addr,
1167             WORD_ALIGNED_OFFSETOF(l2_bd_chain_context_t, l2ctx_max_pkt_len),
1168             rxq->max_pkt_len ?
1169                 rxq->max_pkt_len:
1170                 pdev->params.mtu + 4);  // + 4 L2CRC
1171 
1172 
1173     }
1174 } /* init_l2rxq */
1175 
1176 
1177 
1178 #ifndef EXCLUDE_KQE_SUPPORT
1179 /*******************************************************************************
1180  * Description:
1181  *
1182  * Return:
1183  ******************************************************************************/
1184 STATIC void
1185 init_kq(
1186     lm_device_t *pdev)
1187 {
1188     lm_kq_info_t *kq;
1189     u32_t page_cnt;
1190     u32_t val;
1191 
1192     kq = &pdev->kq_info;
1193 
1194     /* initialize kwq. */
1195     page_cnt = pdev->params.kwq_page_cnt;
1196     if(page_cnt)
1197     {
1198         kq->kwq_cid_addr = GET_CID_ADDR(KWQ_CID);
1199         kq->kwqe_left = (LM_PAGE_SIZE/sizeof(kwqe_t)) * page_cnt - 1;
1200         kq->kwq_last_qe = kq->kwq_virt + kq->kwqe_left;
1201 
1202         setup_page_table(kq->kwq_pgtbl_virt, page_cnt, kq->kwq_phy);
1203 
1204         kq->kwq_prod_idx = 0;
1205         kq->kwq_con_idx = 0;
1206         kq->kwq_prod_qe = kq->kwq_virt;
1207         kq->kwq_con_qe = kq->kwq_virt;
1208         kq->kwqe_left = (LM_PAGE_SIZE/sizeof(kwqe_t)) * page_cnt - 1;
1209 
1210         val = KRNLQ_TYPE_TYPE_KRNLQ << 24;
1211         val |= (((sizeof(krnlq_context_t) + 0x1f) & ~0x1f) / 0x20) << 16;
1212         val |= LM_PAGE_BITS-8;
1213         val |= KRNLQ_FLAGS_QE_SELF_SEQ;
1214         CTX_WR(
1215             pdev,
1216             kq->kwq_cid_addr,
1217             WORD_ALIGNED_OFFSETOF(krnlq_context_t, krnlq_type),
1218             val);
1219 
1220         val = (LM_PAGE_SIZE/sizeof(kwqe_t) - 1) << 16;
1221         CTX_WR(
1222             pdev,
1223             kq->kwq_cid_addr,
1224             WORD_ALIGNED_OFFSETOF(krnlq_context_t, krnlq_qe_self_seq_max),
1225             val);
1226 
1227         val = (LM_PAGE_SIZE/sizeof(kwqe_t)) << 16;
1228         val |= pdev->params.kwq_page_cnt;
1229         CTX_WR(
1230             pdev,
1231             kq->kwq_cid_addr,
1232             WORD_ALIGNED_OFFSETOF(krnlq_context_t, krnlq_pgtbl_npages),
1233             val);
1234 
1235         val = kq->kwq_pgtbl_phy.as_u32.high;
1236         CTX_WR(
1237             pdev,
1238             kq->kwq_cid_addr,
1239             WORD_ALIGNED_OFFSETOF(krnlq_context_t, krnlq_pgtbl_haddr_hi),
1240             val);
1241 
1242         val = kq->kwq_pgtbl_phy.as_u32.low;
1243         CTX_WR(
1244             pdev,
1245             kq->kwq_cid_addr,
1246             WORD_ALIGNED_OFFSETOF(krnlq_context_t, krnlq_pgtbl_haddr_lo),
1247             val);
1248     }
1249 
1250     /* initialize kcq. */
1251     page_cnt = pdev->params.kcq_page_cnt;
1252     if(page_cnt)
1253     {
1254         kq->kcq_cid_addr = GET_CID_ADDR(KCQ_CID);
1255         kq->kcq_last_qe = kq->kcq_virt +
1256             (LM_PAGE_SIZE/sizeof(kcqe_t)) * page_cnt - 1;
1257 
1258         setup_page_table(kq->kcq_pgtbl_virt, page_cnt, kq->kcq_phy);
1259 
1260         kq->kcq_con_idx = 0;
1261         kq->history_kcq_con_idx = 0;
1262         kq->kcq_con_qe = kq->kcq_virt;
1263         kq->history_kcq_con_qe = kq->kcq_virt;
1264 
1265         val = KRNLQ_TYPE_TYPE_KRNLQ << 24;
1266         val |= (((sizeof(krnlq_context_t) + 0x1f) & ~0x1f) / 0x20) << 16;
1267         val |= LM_PAGE_BITS-8;
1268         val |= KRNLQ_FLAGS_QE_SELF_SEQ;
1269         CTX_WR(
1270             pdev,
1271             kq->kcq_cid_addr,
1272             WORD_ALIGNED_OFFSETOF(krnlq_context_t, krnlq_type),
1273             val);
1274 
1275         val = (LM_PAGE_SIZE/sizeof(kwqe_t) - 1) << 16;
1276         CTX_WR(
1277             pdev,
1278             kq->kcq_cid_addr,
1279             WORD_ALIGNED_OFFSETOF(krnlq_context_t, krnlq_qe_self_seq_max),
1280             val);
1281 
1282         val = (LM_PAGE_SIZE/sizeof(kcqe_t)) << 16;
1283         val |= pdev->params.kcq_page_cnt;
1284         CTX_WR(
1285             pdev,
1286             kq->kcq_cid_addr,
1287             WORD_ALIGNED_OFFSETOF(krnlq_context_t, krnlq_pgtbl_npages),
1288             val);
1289 
1290         val = kq->kcq_pgtbl_phy.as_u32.high;
1291         CTX_WR(
1292             pdev,
1293             kq->kcq_cid_addr,
1294             WORD_ALIGNED_OFFSETOF(krnlq_context_t, krnlq_pgtbl_haddr_hi),
1295             val);
1296 
1297         val = kq->kcq_pgtbl_phy.as_u32.low;
1298         CTX_WR(
1299             pdev,
1300             kq->kcq_cid_addr,
1301             WORD_ALIGNED_OFFSETOF(krnlq_context_t, krnlq_pgtbl_haddr_lo),
1302             val);
1303     }
1304 } /* init_kq */
1305 #endif /* EXCLUDE_KQE_SUPPORT */
1306 
1307 /*******************************************************************************
1308  * Description:  Determines the flow control, MAC, and CU trip values
1309  *
1310  * xoff = processing_q_delay + propagation_delay + response_delay +
1311  *        propagation_delay for return path + drop_margin_delay
1312  * xon = xoff + (mtu/mbuf_size)
1313  *
1314  * MAC_drop = drop_margin_low*mtu/mbuf_size
1315  * MAC_keep = drop_margin_high*mtu/mbuf_size
1316  *
1317  * CU_drop =  (drop_margin_low+1)*mtu/mbuf_size
1318  * CU_keep =  (drop_margin_high)*mtu/mbuf_size
1319  *
1320  * processing_q_delay = ((mtu+20)/(64+20))+1)
1321  * propagation_delay = 1
1322  * response_time = 2 (quanta)
1323  * mbuf_size = 128
1324  * response_delay = (response_time*512)/(mbuf_size*8) + (mtu/mbuf_size)
1325  * drop_margin_low = 0.5
1326  * drop_margin_high = 2.5
1327  * drop_margin_mid = 1.5
1328  * drop_margin_delay = (mtu*drop_margin_mid/mbuf_size)
1329  *
1330  * Table:
1331  *
1332  * Return:  Flow control, MAC, and CU trip values
1333  ******************************************************************************/
1334 typedef enum
1335 {
1336     TRIP_FLOW   = 0,
1337     TRIP_MAC    = 1,
1338     TRIP_CU     = 2
1339 } trip_type_t;
1340 
1341 STATIC void
1342 get_trip_val(
1343     trip_type_t type,
1344     u32_t mtu,
1345     u32_t *val,
1346     u8_t  enable_cu_rate_limiter,
1347     u8_t  mbuf_cnt_adj)
1348 {
1349 #define NONJF_MTU_SIZE  1500
1350 #define MTU_STEP        500
1351 
1352     const u32_t trip_tbl[3][2] = {
1353         /* Base value, Increment */
1354 	{ 0x00410036, 0x00140010 }, /* XOFF/XON setting */
1355 	{ 0x001e0006, 0x000a0002 }, /* MAC drop/keep trip setting */
1356 	{ 0x005e0052, 0x000a0006 } /* CU drop/keep trip setting */
1357     };
1358 
1359     const u32_t isolate_rbuf_trip_tbl[3][2] = {
1360         /* Base value, Increment */
1361 	{ 0x0089007e, 0x00140010 }, /* XOFF/XON setting */
1362 	{ 0x0066004e, 0x000a0002 }, /* MAC drop/keep trip setting */
1363 	{ 0x0066004e, 0x000a0006 } /* CU drop/keep trip setting */
1364     };
1365 
1366     if(type > TRIP_CU)
1367         type = 0;   /* Crash prevention */
1368 
1369     *val = 0;
1370     while(mtu > NONJF_MTU_SIZE + MTU_STEP)
1371     {
1372         if(enable_cu_rate_limiter)
1373             *val += isolate_rbuf_trip_tbl[type][1];
1374         else
1375             *val += trip_tbl[type][1];
1376 
1377         mtu -= MTU_STEP;
1378     }
1379     if(enable_cu_rate_limiter)
1380         *val = *val + (isolate_rbuf_trip_tbl[type][0] - (mbuf_cnt_adj<<16 | mbuf_cnt_adj));
1381     else
1382         *val = *val + trip_tbl[type][0];
1383 
1384 } /* get_trip_val */
1385 
1386 
1387 
1388 /*******************************************************************************
1389  * Description:
1390  *
1391  * Return:
1392  ******************************************************************************/
1393 STATIC void
1394 zero_out_sb(
1395     lm_device_t *pdev,
1396     u32_t *sb_ptr)
1397 {
1398     u32_t sb_size;
1399     u32_t offset;
1400 
1401     if(CHIP_NUM(pdev) == CHIP_NUM_5709)
1402     {
1403         sb_size = sizeof(status_blk_combined_t);
1404     }
1405     else
1406     {
1407         sb_size = sizeof(status_block_t);
1408     }
1409 
1410     offset = 0;
1411 
1412     while(offset < sb_size)
1413     {
1414         *sb_ptr = 0;
1415         sb_ptr++;
1416         offset += sizeof(u32_t);
1417     }
1418 } /* zero_out_sb */
1419 
1420 
1421 
1422 /*******************************************************************************
1423  * Description:
1424  *
1425  * Return:
1426  ******************************************************************************/
1427 STATIC void
1428 reduce_ftq_depth(
1429     lm_device_t *pdev)
1430 {
1431     DbgBreakIf(CHIP_REV(pdev) != CHIP_REV_IKOS &&
1432                CHIP_REV(pdev) != CHIP_REV_FPGA);
1433 
1434     REG_WR_IND(
1435         pdev,
1436         OFFSETOF(reg_space_t, com.com_comxq_ftq_ctl),
1437         2 << 12);
1438     REG_WR_IND(
1439         pdev,
1440         OFFSETOF(reg_space_t, com.com_comtq_ftq_ctl),
1441         2 << 12);
1442     REG_WR_IND(
1443         pdev,
1444         OFFSETOF(reg_space_t, com.com_comq_ftq_ctl),
1445         2 << 12);
1446 
1447     REG_WR_IND(
1448         pdev,
1449         OFFSETOF(reg_space_t, cp.cp_cpq_ftq_ctl),
1450         4 << 12);
1451 
1452     REG_WR(pdev, csch.csch_ch_ftq_ctl, 8 << 12);
1453 
1454     REG_WR_IND(
1455         pdev,
1456         OFFSETOF(reg_space_t, mcp.mcp_mcpq_ftq_ctl),
1457         32 << 12);
1458 
1459     REG_WR(pdev, rdma.rdma_ftq_ctl, 2 << 12);
1460 
1461     REG_WR(pdev, rlup.rlup_ftq_ctl, 8 << 12);
1462 
1463     REG_WR(pdev, rv2p.rv2p_pftq_ctl, 2 << 12);
1464     REG_WR(pdev, rv2p.rv2p_tftq_ctl, 2 << 12);
1465     REG_WR(pdev, rv2p.rv2p_mftq_ctl, 4 << 12);
1466 
1467     REG_WR_IND(
1468         pdev,
1469         OFFSETOF(reg_space_t, rxp.rxp_cftq_ctl),
1470         8 << 12);
1471     REG_WR_IND(
1472         pdev,
1473         OFFSETOF(reg_space_t, rxp.rxp_ftq_ctl),
1474         8 << 12);
1475 
1476     REG_WR_IND(
1477         pdev,
1478         OFFSETOF(reg_space_t, tas.tas_ftq_ctl),
1479         16 << 12);
1480 
1481     REG_WR(pdev, tbdr.tbdr_ftq_ctl, 2 << 12);
1482 
1483     REG_WR(pdev, tdma.tdma_ftq_ctl, 2 << 12);
1484 
1485     REG_WR_IND(
1486         pdev,
1487         OFFSETOF(reg_space_t, tpat.tpat_ftq_ctl),
1488         16 << 12);
1489 
1490     REG_WR(pdev, tsch.tsch_ftq_ctl, 2 << 12);
1491 
1492     REG_WR_IND(
1493         pdev,
1494         OFFSETOF(reg_space_t, txp.txp_ftq_ctl),
1495         2 << 12);
1496 } /* reduce_ftq_depth */
1497 
1498 
1499 
1500 /*******************************************************************************
1501  * Description:
1502  *
1503  * Return:
1504  ******************************************************************************/
1505 STATIC void
1506 init_5709_for_msix(
1507     lm_device_t *pdev)
1508 {
1509     u32_t val;
1510 
1511     DbgBreakIf(CHIP_NUM(pdev) != CHIP_NUM_5709);
1512 
1513     REG_WR(pdev,
1514            pci.pci_grc_window_addr,
1515            (pdev->hw_info.shmem_base & ~0x7fff) |
1516             PCI_GRC_WINDOW_ADDR_SEP_WIN);
1517 
1518     REG_WR(pdev,
1519            pci.pci_grc_window1_addr,
1520            (pdev->hw_info.shmem_base & ~0x7fff) + 0x6000 /*0x16e000 */);
1521 
1522     REG_RD(pdev, pci_config.pcicfg_msix_control, &val);
1523     switch(pdev->vars.interrupt_mode)
1524     {
1525         case IRQ_MODE_MSIX_BASED:
1526             /* enable all msix vectors */
1527             REG_WR(pdev,
1528                 hc.hc_msix_bit_vector,
1529                 HC_MSIX_BIT_VECTOR_VAL);
1530         break;
1531 
1532         case IRQ_MODE_MSI_BASED:
1533             /* enable 16 messages so hardware will
1534              * generate maximum of 9 messages
1535              */
1536             REG_RD(pdev,
1537                    pci_config.pcicfg_msi_control,
1538                    &val);
1539             val &= PCICFG_MSI_CONTROL_MENA;
1540             val |= PCICFG_MSI_CONTROL_MENA_16;
1541             REG_WR(pdev,
1542                    pci_config.pcicfg_msi_control,
1543                    (u16_t)val);
1544         break;
1545 
1546         case IRQ_MODE_SIMD:
1547             /* tell the chip that we are in single isr/multiple dpc mode */
1548             if(val & PCICFG_MSIX_CONTROL_MSIX_ENABLE)
1549             {
1550                 u32_t idx, addr_l, addr_h, vec_data;
1551 
1552                 REG_WR(pdev,
1553                        hc.hc_msix_bit_vector,
1554                        HC_MSIX_BIT_VECTOR_VAL);
1555 
1556                 REG_RD_IND(
1557                     pdev,
1558                     OFFSETOF(reg_space_t, hc1.hc1_msix_vector0_addr_l),
1559                     &addr_l);
1560                 REG_RD_IND(
1561                     pdev,
1562                     OFFSETOF(reg_space_t, hc1.hc1_msix_vector0_addr_h),
1563                     &addr_h);
1564                 REG_RD_IND(
1565                     pdev,
1566                     OFFSETOF(reg_space_t, hc1.hc1_msix_vector0_data),
1567                     &vec_data);
1568                 for(idx = 1; idx < 9; idx++)
1569                 {
1570                     REG_WR_IND(
1571                         pdev,
1572                         OFFSETOF(reg_space_t,
1573                                  hc1.hc1_msix_vector0_addr_l) +
1574                                  idx*4*sizeof(u32_t),
1575                         addr_l);
1576                     REG_WR_IND(
1577                         pdev,
1578                         OFFSETOF(reg_space_t,
1579                                  hc1.hc1_msix_vector0_addr_h) +
1580                                  idx*4*sizeof(u32_t),
1581                         addr_h);
1582                     REG_WR_IND(
1583                         pdev,
1584                         OFFSETOF(reg_space_t,
1585                                  hc1.hc1_msix_vector0_data) +
1586                                  idx*4*sizeof(u32_t),
1587                         vec_data);
1588                 }
1589             }
1590             else
1591             {
1592                 REG_RD(pdev,
1593                        pci_config.pcicfg_msi_control,
1594                        &val);
1595                 val &= ~PCICFG_MSI_CONTROL_MENA;
1596                 REG_WR(pdev,
1597                        pci_config.pcicfg_msi_control,
1598                        (u16_t)val);
1599             }
1600         break;
1601 
1602         case IRQ_MODE_LINE_BASED:
1603             /* do nothing */
1604         break;
1605 
1606         default:
1607             DbgBreakMsg("Unknown interrupt mode\n");
1608             break;
1609     }
1610 
1611     REG_WR(pdev,
1612            pci.pci_grc_window2_addr,
1613            MSIX_TABLE_ADDR /*MSIX vector addr */);
1614     REG_WR(pdev,
1615            pci.pci_grc_window3_addr,
1616            MSIX_PBA_ADDR /*MSIX PBA addr */);
1617     REG_WR(pdev, pci.pci_msix_tbl_off_bir, PCI_GRC_WINDOW2_BASE);
1618     REG_WR(pdev, pci.pci_msix_pba_off_bit, PCI_GRC_WINDOW3_BASE);
1619 } /* init_5709_for_msix */
1620 
1621 
1622 
1623 /*******************************************************************************
1624  * Description:
1625  *
1626  * Return:
1627  ******************************************************************************/
1628 STATIC void
1629 init_hc(
1630     lm_device_t *pdev)
1631 {
1632     u32_t val;
1633 
1634     /* Set HC timer mode. */
1635     REG_RD(pdev, hc.hc_config, &val);
1636     val &= ~(HC_CONFIG_RX_TMR_MODE | HC_CONFIG_TX_TMR_MODE |
1637         HC_CONFIG_COM_TMR_MODE | HC_CONFIG_CMD_TMR_MODE);
1638 
1639     if(pdev->params.hc_timer_mode & HC_RX_TIMER_MODE)
1640     {
1641         val |= HC_CONFIG_RX_TMR_MODE;
1642     }
1643 
1644     if(pdev->params.hc_timer_mode & HC_TX_TIMER_MODE)
1645     {
1646         val |= HC_CONFIG_TX_TMR_MODE;
1647     }
1648 
1649     if(pdev->params.hc_timer_mode & HC_COM_TIMER_MODE)
1650     {
1651         val |= HC_CONFIG_COM_TMR_MODE;
1652     }
1653 
1654     if(pdev->params.hc_timer_mode & HC_CMD_TIMER_MODE)
1655     {
1656         val |= HC_CONFIG_CMD_TMR_MODE;
1657     }
1658 
1659     if(CHIP_NUM(pdev) == CHIP_NUM_5709)
1660     {
1661         val &= ~HC_CONFIG_SET_MASK_AT_RD;
1662         //if(pdev->vars.interrupt_mode > IRQ_MODE_SIMD)
1663         //{
1664         //    val |= HC_CONFIG_ONE_SHOT;
1665         //}
1666     }
1667 
1668     REG_WR(pdev, hc.hc_config, val);
1669 
1670     /* Enable timer abort a attention which is used to request
1671      * the driver to write a driver pulse to the firmware. */
1672     REG_RD(pdev, hc.hc_attn_bits_enable, &val);
1673     val |= STATUS_ATTN_BITS_TIMER_ABORT;
1674     REG_WR(pdev, hc.hc_attn_bits_enable, val);
1675 
1676     /* Set HC parameters. */
1677     REG_WR(pdev, hc.hc_status_addr_l, pdev->vars.status_phy.as_u32.low);
1678     REG_WR(pdev, hc.hc_status_addr_h, pdev->vars.status_phy.as_u32.high);
1679 
1680     REG_WR(pdev, hc.hc_statistics_addr_l, pdev->vars.stats_phy.as_u32.low);
1681     REG_WR(pdev, hc.hc_statistics_addr_h, pdev->vars.stats_phy.as_u32.high);
1682 
1683     REG_WR(
1684         pdev,
1685         hc.hc_tx_quick_cons_trip,
1686         (pdev->params.tx_quick_cons_trip_int << 16) |
1687             pdev->params.tx_quick_cons_trip);
1688     REG_WR(
1689         pdev,
1690         hc.hc_rx_quick_cons_trip,
1691         (pdev->params.rx_quick_cons_trip_int << 16) |
1692             pdev->params.rx_quick_cons_trip);
1693     REG_WR(
1694         pdev,
1695         hc.hc_comp_prod_trip,
1696         (pdev->params.comp_prod_trip_int << 16) |
1697             pdev->params.comp_prod_trip);
1698     REG_WR(
1699         pdev,
1700         hc.hc_tx_ticks,
1701         (pdev->params.tx_ticks_int << 16) |
1702             pdev->params.tx_ticks);
1703     REG_WR(
1704         pdev,
1705         hc.hc_rx_ticks,
1706         (pdev->params.rx_ticks_int << 16) |
1707             pdev->params.rx_ticks);
1708     REG_WR(
1709         pdev,
1710         hc.hc_com_ticks,
1711         (pdev->params.com_ticks_int << 16) |
1712             pdev->params.com_ticks);
1713     REG_WR(
1714         pdev, hc.hc_cmd_ticks,
1715         (pdev->params.cmd_ticks_int << 16) |
1716             pdev->params.cmd_ticks);
1717 
1718     val = pdev->params.stats_ticks;
1719     if(CHIP_REV(pdev) == CHIP_REV_IKOS)
1720     {
1721         val = val / 1000;
1722         if(val < 0x100)
1723         {
1724             val = 0x100;
1725         }
1726     }
1727     REG_WR(pdev, hc.hc_stats_ticks, val);
1728 
1729     REG_WR(pdev, hc.hc_stat_collect_ticks, 0xbb8);  /* 3ms */
1730     REG_WR(pdev, hc.hc_command, HC_COMMAND_CLR_STAT_NOW);
1731 } /* init_hc */
1732 
1733 
1734 
1735 /*******************************************************************************
1736  * Description:
1737  *
1738  * Return:
1739  ******************************************************************************/
1740 STATIC void
1741 init_hc_for_5709(
1742     lm_device_t *pdev)
1743 {
1744     DbgBreakIf(CHIP_NUM(pdev) != CHIP_NUM_5709);
1745 
1746     init_hc(pdev);
1747 
1748     REG_WR(pdev, hc.hc_tx_quick_cons_trip_1, pdev->params.psb_tx_cons_trip);
1749     REG_WR(pdev, hc.hc_tx_ticks_1, pdev->params.psb_tx_ticks);
1750     REG_WR(pdev, hc.hc_rx_quick_cons_trip_1, pdev->params.psb_rx_cons_trip);
1751     REG_WR(pdev, hc.hc_rx_ticks_1, pdev->params.psb_rx_ticks);
1752     REG_WR(pdev, hc.hc_comp_prod_trip_1, pdev->params.psb_comp_prod_trip);
1753     REG_WR(pdev, hc.hc_com_ticks_1, pdev->params.psb_com_ticks);
1754     REG_WR(pdev, hc.hc_cmd_ticks_1, pdev->params.psb_cmd_ticks);
1755     REG_WR(pdev, hc.hc_periodic_ticks_1, pdev->params.psb_period_ticks);
1756     //if(pdev->vars.interrupt_mode > IRQ_MODE_SIMD)
1757     //{
1758     //    REG_RD(pdev, hc.hc_sb_config_1, &val);
1759     //    val |= HC_SB_CONFIG_1_ONE_SHOT;
1760     //    REG_WR(pdev, hc.hc_sb_config_1, val);
1761     //}
1762 
1763     REG_WR(pdev, hc.hc_tx_quick_cons_trip_2, pdev->params.psb_tx_cons_trip);
1764     REG_WR(pdev, hc.hc_tx_ticks_2, pdev->params.psb_tx_ticks);
1765     REG_WR(pdev, hc.hc_rx_quick_cons_trip_2, pdev->params.psb_rx_cons_trip);
1766     REG_WR(pdev, hc.hc_rx_ticks_2, pdev->params.psb_rx_ticks);
1767     REG_WR(pdev, hc.hc_comp_prod_trip_2, pdev->params.psb_comp_prod_trip);
1768     REG_WR(pdev, hc.hc_com_ticks_2, pdev->params.psb_com_ticks);
1769     REG_WR(pdev, hc.hc_cmd_ticks_2, pdev->params.psb_cmd_ticks);
1770     REG_WR(pdev, hc.hc_periodic_ticks_2, pdev->params.psb_period_ticks);
1771     //if(pdev->vars.interrupt_mode > IRQ_MODE_SIMD)
1772     //{
1773     //    REG_RD(pdev, hc.hc_sb_config_2, &val);
1774     //    val |= HC_SB_CONFIG_2_ONE_SHOT;
1775     //    REG_WR(pdev, hc.hc_sb_config_2, val);
1776     //}
1777 
1778     REG_WR(pdev, hc.hc_tx_quick_cons_trip_3, pdev->params.psb_tx_cons_trip);
1779     REG_WR(pdev, hc.hc_tx_ticks_3, pdev->params.psb_tx_ticks);
1780     REG_WR(pdev, hc.hc_rx_quick_cons_trip_3, pdev->params.psb_rx_cons_trip);
1781     REG_WR(pdev, hc.hc_rx_ticks_3, pdev->params.psb_rx_ticks);
1782     REG_WR(pdev, hc.hc_comp_prod_trip_3, pdev->params.psb_comp_prod_trip);
1783     REG_WR(pdev, hc.hc_com_ticks_3, pdev->params.psb_com_ticks);
1784     REG_WR(pdev, hc.hc_cmd_ticks_3, pdev->params.psb_cmd_ticks);
1785     REG_WR(pdev, hc.hc_periodic_ticks_3, pdev->params.psb_period_ticks);
1786     //if(pdev->vars.interrupt_mode > IRQ_MODE_SIMD)
1787     //{
1788     //    REG_RD(pdev, hc.hc_sb_config_3, &val);
1789     //    val |= HC_SB_CONFIG_3_ONE_SHOT;
1790     //    REG_WR(pdev, hc.hc_sb_config_3, val);
1791     //}
1792 
1793     REG_WR(pdev, hc.hc_tx_quick_cons_trip_4, pdev->params.psb_tx_cons_trip);
1794     REG_WR(pdev, hc.hc_tx_ticks_4, pdev->params.psb_tx_ticks);
1795     REG_WR(pdev, hc.hc_rx_quick_cons_trip_4, pdev->params.psb_rx_cons_trip);
1796     REG_WR(pdev, hc.hc_rx_ticks_4, pdev->params.psb_rx_ticks);
1797     REG_WR(pdev, hc.hc_comp_prod_trip_4, pdev->params.psb_comp_prod_trip);
1798     REG_WR(pdev, hc.hc_com_ticks_4, pdev->params.psb_com_ticks);
1799     REG_WR(pdev, hc.hc_cmd_ticks_4, pdev->params.psb_cmd_ticks);
1800     REG_WR(pdev, hc.hc_periodic_ticks_4, pdev->params.psb_period_ticks);
1801     //if(pdev->vars.interrupt_mode > IRQ_MODE_SIMD)
1802     //{
1803     //    REG_RD(pdev, hc.hc_sb_config_4, &val);
1804     //    val |= HC_SB_CONFIG_4_ONE_SHOT;
1805     //    REG_WR(pdev, hc.hc_sb_config_4, val);
1806     //}
1807 
1808     REG_WR(pdev, hc.hc_tx_quick_cons_trip_5, pdev->params.psb_tx_cons_trip);
1809     REG_WR(pdev, hc.hc_tx_ticks_5, pdev->params.psb_tx_ticks);
1810     REG_WR(pdev, hc.hc_rx_quick_cons_trip_5, pdev->params.psb_rx_cons_trip);
1811     REG_WR(pdev, hc.hc_rx_ticks_5, pdev->params.psb_rx_ticks);
1812     REG_WR(pdev, hc.hc_comp_prod_trip_5, pdev->params.psb_comp_prod_trip);
1813     REG_WR(pdev, hc.hc_com_ticks_5, pdev->params.psb_com_ticks);
1814     REG_WR(pdev, hc.hc_cmd_ticks_5, pdev->params.psb_cmd_ticks);
1815     REG_WR(pdev, hc.hc_periodic_ticks_5, pdev->params.psb_period_ticks);
1816     //if(pdev->vars.interrupt_mode > IRQ_MODE_SIMD)
1817     //{
1818     //    REG_RD(pdev, hc.hc_sb_config_5, &val);
1819     //    val |= HC_SB_CONFIG_5_ONE_SHOT;
1820     //    REG_WR(pdev, hc.hc_sb_config_5, val);
1821     //}
1822 
1823     REG_WR(pdev, hc.hc_tx_quick_cons_trip_6, pdev->params.psb_tx_cons_trip);
1824     REG_WR(pdev, hc.hc_tx_ticks_6, pdev->params.psb_tx_ticks);
1825     REG_WR(pdev, hc.hc_rx_quick_cons_trip_6, pdev->params.psb_rx_cons_trip);
1826     REG_WR(pdev, hc.hc_rx_ticks_6, pdev->params.psb_rx_ticks);
1827     REG_WR(pdev, hc.hc_comp_prod_trip_6, pdev->params.psb_comp_prod_trip);
1828     REG_WR(pdev, hc.hc_com_ticks_6, pdev->params.psb_com_ticks);
1829     REG_WR(pdev, hc.hc_cmd_ticks_6, pdev->params.psb_cmd_ticks);
1830     REG_WR(pdev, hc.hc_periodic_ticks_6, pdev->params.psb_period_ticks);
1831     //if(pdev->vars.interrupt_mode > IRQ_MODE_SIMD)
1832     //{
1833     //    REG_RD(pdev, hc.hc_sb_config_6, &val);
1834     //    val |= HC_SB_CONFIG_6_ONE_SHOT;
1835     //    REG_WR(pdev, hc.hc_sb_config_6, val);
1836     //}
1837 
1838     REG_WR(pdev, hc.hc_tx_quick_cons_trip_7, pdev->params.psb_tx_cons_trip);
1839     REG_WR(pdev, hc.hc_tx_ticks_7, pdev->params.psb_tx_ticks);
1840     REG_WR(pdev, hc.hc_rx_quick_cons_trip_7, pdev->params.psb_rx_cons_trip);
1841     REG_WR(pdev, hc.hc_rx_ticks_7, pdev->params.psb_rx_ticks);
1842     REG_WR(pdev, hc.hc_comp_prod_trip_7, pdev->params.psb_comp_prod_trip);
1843     REG_WR(pdev, hc.hc_com_ticks_7, pdev->params.psb_com_ticks);
1844     REG_WR(pdev, hc.hc_cmd_ticks_7, pdev->params.psb_cmd_ticks);
1845     REG_WR(pdev, hc.hc_periodic_ticks_7, pdev->params.psb_period_ticks);
1846     //if(pdev->vars.interrupt_mode > IRQ_MODE_SIMD)
1847     //{
1848     //    REG_RD(pdev, hc.hc_sb_config_7, &val);
1849     //    val |= HC_SB_CONFIG_7_ONE_SHOT;
1850     //    REG_WR(pdev, hc.hc_sb_config_7, val);
1851     //}
1852 
1853     REG_WR(pdev, hc.hc_tx_quick_cons_trip_8, pdev->params.psb_tx_cons_trip);
1854     REG_WR(pdev, hc.hc_tx_ticks_8, pdev->params.psb_tx_ticks);
1855     REG_WR(pdev, hc.hc_rx_quick_cons_trip_8, pdev->params.psb_rx_cons_trip);
1856     REG_WR(pdev, hc.hc_rx_ticks_8, pdev->params.psb_rx_ticks);
1857     REG_WR(pdev, hc.hc_comp_prod_trip_8, pdev->params.psb_comp_prod_trip);
1858     REG_WR(pdev, hc.hc_com_ticks_8, pdev->params.psb_com_ticks);
1859     REG_WR(pdev, hc.hc_cmd_ticks_8, pdev->params.psb_cmd_ticks);
1860     REG_WR(pdev, hc.hc_periodic_ticks_8, pdev->params.psb_period_ticks);
1861     //if(pdev->vars.interrupt_mode > IRQ_MODE_SIMD)
1862     //{
1863     //    REG_RD(pdev, hc.hc_sb_config_8, &val);
1864     //    val |= HC_SB_CONFIG_8_ONE_SHOT;
1865     //    REG_WR(pdev, hc.hc_sb_config_8, val);
1866     //}
1867 } /* init_hc_for_5709 */
1868 
1869 
1870 
1871 /*******************************************************************************
1872  * Description:
1873  *
1874  * Return:
1875  ******************************************************************************/
1876 STATIC void
1877 init_hc_for_57728(
1878     lm_device_t *pdev)
1879 {
1880     init_hc(pdev);
1881     init_hc_for_5709(pdev);
1882 
1883     #if X1V_havhavhav
1884     REG_WR(pdev, hc.hc_sb_haddr_0_lo, pdev->vars.status_phy.as_u32.low);
1885     REG_WR(pdev, hc.hc_sb_haddr_0_hi, pdev->vars.status_phy.as_u32.high);
1886 
1887     REG_WR(pdev, hc.hc_sb_select_0_config,
1888             ENABLE | fid == 7 | param-sel = 0 | haddr_sel = 0 |
1889             haddr_idx_sel = 0);
1890     REG_WR(pdev, hc.hc_sb_select_1_config,
1891             ENABLE | fid == 1 | param-sel = 0 | haddr_sel = 0 |
1892             haddr_idx_sel = 7);
1893     REG_WR(pdev, hc.hc_sb_select_2_config,
1894             ENABLE | fid == 7 | param-sel = 0 | haddr_sel = 0 |
1895             haddr_idx_sel = 2);
1896     REG_WR(pdev, hc.hc_sb_select_3_config,
1897             ENABLE | fid == 7 | param-sel = 0 | haddr_sel = 0 |
1898             haddr_idx_sel = 3);
1899     REG_WR(pdev, hc.hc_sb_select_4_config,
1900             ENABLE | fid == 7 | param-sel = 0 | haddr_sel = 0 |
1901             haddr_idx_sel = 4);
1902     REG_WR(pdev, hc.hc_sb_select_5_config,
1903             ENABLE | fid == 7 | param-sel = 0 | haddr_sel = 0 |
1904             haddr_idx_sel = 5);
1905     REG_WR(pdev, hc.hc_sb_select_6_config,
1906             ENABLE | fid == 7 | param-sel = 0 | haddr_sel = 0 |
1907             haddr_idx_sel = 6);
1908     REG_WR(pdev, hc.hc_sb_select_7_config,
1909             ENABLE | fid == 7 | param-sel = 0 | haddr_sel = 0 |
1910             haddr_idx_sel = 7);
1911     REG_WR(pdev, hc.hc_sb_select_8_config,
1912             ENABLE | fid == 7 | param-sel = 0 | haddr_sel = 0 |
1913             haddr_idx_sel = 8);
1914     REG_WR(pdev, hc.hc_sb_select_8_config,
1915             ENABLE | fid == 7 | param-sel = 0 | haddr_sel = 0 |
1916             haddr_idx_sel = 9);
1917     REG_WR(pdev, hc.hc_sb_select_8_config,
1918             ENABLE | fid == 7 | param-sel = 0 | haddr_sel = 0 |
1919             haddr_idx_sel = 10);
1920     REG_WR(pdev, hc.hc_sb_select_8_config,
1921             ENABLE | fid == 7 | param-sel = 0 | haddr_sel = 0 |
1922             haddr_idx_sel = 11);
1923     REG_WR(pdev, hc.hc_sb_select_8_config,
1924             ENABLE | fid == 7 | param-sel = 0 | haddr_sel = 0 |
1925             haddr_idx_sel = 12);
1926     REG_WR(pdev, hc.hc_sb_select_8_config,
1927             ENABLE | fid == 7 | param-sel = 0 | haddr_sel = 0 |
1928             haddr_idx_sel = 13);
1929     REG_WR(pdev, hc.hc_sb_select_8_config,
1930             ENABLE | fid == 7 | param-sel = 0 | haddr_sel = 0 |
1931             haddr_idx_sel = 14);
1932     REG_WR(pdev, hc.hc_sb_select_8_config,
1933             ENABLE | fid == 7 | param-sel = 0 | haddr_sel = 0 |
1934             haddr_idx_sel = 15);
1935     REG_WR(pdev, hc.hc_sb_select_8_config,
1936             ENABLE | fid == 7 | param-sel = 0 | haddr_sel = 0 |
1937             haddr_idx_sel = 16);
1938     #endif
1939 } /* init_hc_for_57728 */
1940 
1941 
1942 
1943 /*******************************************************************************
1944  * Description:
1945  *
1946  * Return:
1947  ******************************************************************************/
1948 
1949 // Refer to TetonII Register spec, setting bits in krl_???_mask1 and
1950 // krl_???_mask2 will cause the corresponding engine (CP or RV2P) to be
1951 // activated when any word enabled by this mask is written. Mask1 is
1952 // for first 128 bytes and mask2 is for second 128 bytes.
1953 // Each bit in the mask correspond to a 32 bit word in the kernal area.
1954 // e.g. Writing 0x2000 to the mask2 means activating the engine
1955 // when context location 0xB4 is being written
1956 // (i.e. (0xB4 - 128)/sizeof(u32_t) = bit 13
1957 #define KNL_L4_MASK(field)    \
1958     (1<<(OFFSETOF(l4_context_t, l4ctx_l4_bd_chain_##field) & ~0x80)/sizeof(u32_t))
1959 
1960 #define KNL_L5_MASK(field)    \
1961     (1<<(OFFSETOF(l5_context_t, l5ctx_##field) & ~0x80)/sizeof(u32_t))
1962 
1963 lm_status_t
1964 lm_reset_setup(
1965     lm_device_t *pdev,
1966     u32_t reset_reason)
1967 {
1968     u32_t val;
1969     u8_t  mbuf_adj = 0;
1970 
1971     lm_chip_reset(pdev, reset_reason);
1972 
1973     /* Teton family of chips does not support PCI-X relax ordering. */
1974     if(pdev->hw_info.bus_mode == BUS_MODE_PCIX)
1975     {
1976         REG_RD_OFFSET(
1977             pdev,
1978             OFFSETOF(reg_space_t, pci_config.pcicfg_pcix_cap_id),
1979             &val);
1980         val &= ~(PCICFG_PCIX_COMMAND_RELAX_ORDER << 16);
1981         REG_WR_OFFSET(
1982             pdev,
1983             OFFSETOF(reg_space_t, pci_config.pcicfg_pcix_cap_id),
1984             val);
1985     }
1986 
1987     /* 5709 devices have interrupts enabled by default
1988      * after a hardware reset.  Disable them.
1989      */
1990     lm_disable_int(pdev);
1991 
1992     /* The linkready signal going to the MAC is qualified by a port
1993      * mode of GMII or MII.  When the port mode is NONE, the linkready
1994      * signal is always deasserted when when link is active.  Thus for
1995      * us to get a link change event, we need to set the port mode to
1996      * something other than NONE.  This logic may change in future
1997      * version of the chip.
1998      *
1999      * Also when the port mode is set NONE, the register read/write
2000      * to the emac block (0x1408) will cause the TETON-II FPGA to
2001      * lock up.  This is not seen with the original TETON FPGA. */
2002     REG_WR(pdev, emac.emac_mode, EMAC_MODE_EXT_LINK_POL | EMAC_MODE_PORT_GMII);
2003 
2004     /* Setup DMA configuration. The swap settings are what the device will
2005      * will do, not the net result you want.  This is because there could
2006      * be swapping by intermediary devices (pci bridges). */
2007     val = DMA_CONFIG_DATA_BYTE_SWAP_TE |
2008         DMA_CONFIG_DATA_WORD_SWAP_TE |
2009         DMA_CONFIG_CNTL_WORD_SWAP_TE |
2010 #ifdef BIG_ENDIAN
2011         DMA_CONFIG_CNTL_BYTE_SWAP_TE |
2012 #endif
2013         (pdev->params.num_rchans & 0xf) << 12 |
2014         (pdev->params.num_wchans & 0xf) << 16;
2015 
2016     /* Workaround for data corruption on Intel 840/860 chipset. */
2017     if(pdev->params.ping_pong_dma)
2018     {
2019         val |= DMA_CONFIG_CNTL_PING_PONG_DMA_TE;
2020     }
2021 
2022     /* Apply workaround to avoid race condition in DMA completion
2023      * and write to DMA buffer memory.  This configuration should be
2024      * enabled on all versions of 5706.  */
2025     val |= (0x2<<20) | (1<<11);
2026 
2027     /* Enable delayed completion. */
2028     if(pdev->hw_info.bus_mode == BUS_MODE_PCIX &&
2029         pdev->hw_info.bus_speed == BUS_SPEED_133_MHZ &&
2030         CHIP_ID(pdev) != CHIP_ID_5706_A0)
2031     {
2032         val |= 1 << 23;
2033     }
2034 
2035     /* Configure the clock ratio in the FPGA mode. */
2036     if(CHIP_REV(pdev) == CHIP_REV_FPGA)
2037     {
2038         val |= 0x100;
2039     }
2040 
2041     REG_WR(pdev, dma.dma_config, val);
2042 
2043     if(pdev->params.one_tdma)
2044     {
2045         REG_RD(pdev, tdma.tdma_config, &val);
2046         val |= TDMA_CONFIG_ONE_DMA;
2047         REG_WR(pdev, tdma.tdma_config, val);
2048     }
2049 
2050     if(CHIP_REV(pdev) == CHIP_REV_FPGA)
2051     {
2052         REG_RD(pdev, pci.pci_config_2, &val);
2053         val &= ~0x02000000;
2054         REG_WR(pdev, pci.pci_config_2, val);
2055     }
2056 
2057     /* We need to enable the context block so we can initialize context
2058      * memory.
2059      *
2060      * We also need to enable HC so it can record the link state and the
2061      * first status block update we get will reflect the current state.
2062      *
2063      * We need to enable RV2P in order to download the firmwares for
2064      * its two processors. */
2065     REG_WR(
2066         pdev,
2067         misc.misc_enable_set_bits,
2068         MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
2069             MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
2070             MISC_ENABLE_SET_BITS_DMA_ENGINE_ENABLE |
2071             MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
2072 
2073     /* Initialize context mapping and zero out the quick contexts.  The
2074      * context block must have already been enabled. */
2075     if(CHIP_ID(pdev) == CHIP_ID_5706_A0)
2076     {
2077         init_context_5706_a0_wa(pdev);
2078     }
2079     else if(CHIP_NUM(pdev) == CHIP_NUM_5706 || CHIP_NUM(pdev) == CHIP_NUM_5708)
2080     {
2081         init_context_5706(pdev);
2082     }
2083     else if(CHIP_NUM(pdev) == CHIP_NUM_5709)
2084     {
2085         init_context_5709(pdev);
2086         #if 0
2087         /* Temporary L4 fix. */
2088         // if(CHIP_ID(pdev) == CHIP_ID_5709_IKOS ||
2089         //    CHIP_ID(pdev) == CHIP_ID_5709_FPGA)
2090         {
2091             REG_WR(pdev, mq.mq_map_l4_0, 0x8001c1b9);
2092         }
2093         #endif
2094 
2095         REG_WR(pdev, mq.mq_map_l4_0, 0x80010db9);
2096         REG_WR(pdev, mq.mq_map_l4_4, 0x82810eb2);
2097         REG_WR(pdev, mq.mq_map_l4_5, 0x8f0113b4);
2098     }
2099     else
2100     {
2101         DbgBreakIf(1);
2102     }
2103 
2104     if(pdev->params.test_mode & TEST_MODE_XDIAG_ISCSI)
2105     {
2106         lm_init_cpus(pdev, CPU_RV2P_1 | CPU_RV2P_2); /* other CPUs are loaded through TCL */
2107     }
2108     else
2109     {
2110         lm_init_cpus(pdev, CPU_ALL);
2111     }
2112 
2113     if(CHIP_NUM(pdev) == CHIP_NUM_5709)
2114     {
2115         REG_RD_IND(
2116             pdev,
2117             OFFSETOF(reg_space_t, rxp.rxp_scratch[0])+
2118             RXP_HSI_OFFSETOFF(hw_filter_ctx_offset),
2119             &pdev->vars.hw_filter_ctx_offset);
2120 
2121         init_5709_for_msix(pdev);
2122     }
2123 
2124     lm_nvram_init(pdev, FALSE);
2125 
2126     /* tcp_syn_dos_defense - let the firmware route all the packets with
2127      * TCP SYN bit set to rx chain #1. */
2128     REG_WR_IND(
2129             pdev,
2130             OFFSETOF(reg_space_t, rxp.rxp_scratch[0])+RXP_HSI_OFFSETOFF(tcp_syn_dos_defense),
2131             pdev->params.enable_syn_rcvq);
2132 
2133     REG_RD(pdev, mq.mq_config, &val);
2134     val &= ~MQ_CONFIG_KNL_BYP_BLK_SIZE;
2135     switch((LM_PAGE_BITS - 8) << 4)
2136     {
2137         case MQ_CONFIG_KNL_BYP_BLK_SIZE_256:
2138             val |= MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
2139             break;
2140 
2141         case MQ_CONFIG_KNL_BYP_BLK_SIZE_512:
2142             val |= MQ_CONFIG_KNL_BYP_BLK_SIZE_512;
2143             break;
2144 
2145         case MQ_CONFIG_KNL_BYP_BLK_SIZE_1K:
2146             val |= MQ_CONFIG_KNL_BYP_BLK_SIZE_1K;
2147             break;
2148 
2149         case MQ_CONFIG_KNL_BYP_BLK_SIZE_2K:
2150             val |= MQ_CONFIG_KNL_BYP_BLK_SIZE_2K;
2151             break;
2152 
2153         case MQ_CONFIG_KNL_BYP_BLK_SIZE_4K:
2154             val |= MQ_CONFIG_KNL_BYP_BLK_SIZE_4K;
2155             break;
2156 
2157         default:
2158             DbgBreakMsg("Not supported page size.\n");
2159             break;
2160     }
2161 
2162     if(pdev->params.bin_mq_mode)
2163     {
2164         DbgBreakIf(CHIP_NUM(pdev) != CHIP_NUM_5709);
2165 
2166         val |= MQ_CONFIG_BIN_MQ_MODE;
2167     }
2168 
2169     REG_WR(pdev, mq.mq_config, val);
2170 
2171     /* Configure the end of the kernel mailboxq window and the start of the
2172      * kernel bypass mailboxq. */
2173     val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
2174     REG_WR(pdev, mq.mq_knl_byp_wind_start, val);
2175     REG_WR(pdev, mq.mq_knl_wind_end, val);
2176 
2177     /* Configure page size. */
2178     REG_RD(pdev, tbdr.tbdr_config, &val);
2179     val &= ~TBDR_CONFIG_PAGE_SIZE;
2180     val |= (LM_PAGE_BITS - 8) << 24 | 0x40;
2181     REG_WR(pdev, tbdr.tbdr_config, val);
2182 
2183     /* Program the MTU.  Also include 4 bytes for CRC32. */
2184     val = pdev->params.mtu+4;
2185     if(pdev->params.mtu > MAX_ETHERNET_PACKET_SIZE)
2186     {
2187         val |= EMAC_RX_MTU_SIZE_JUMBO_ENA;
2188     }
2189     REG_WR(pdev, emac.emac_rx_mtu_size, val);
2190 
2191     if(pdev->vars.enable_cu_rate_limiter)
2192     {
2193         if(pdev->vars.cu_mbuf_cnt > 0x48)
2194         {
2195             /* only allow cu mbuf cluster cnt up to 0x48 to accomodate jumbo
2196              * frame size of 9018 ( note: each mbuf cluster is 128 bytes) */
2197             pdev->vars.cu_mbuf_cnt = 0x48;
2198         }
2199 
2200         if(pdev->vars.cu_mbuf_cnt == 0)
2201         {
2202             /* chip default use 8k cu mbuf */
2203             mbuf_adj = 0x48 - 0x40;
2204         }
2205         else
2206         {
2207             mbuf_adj = 0x48 - pdev->vars.cu_mbuf_cnt;
2208         }
2209     }
2210     /* Added flow control trip setup, JF or non-JF */
2211     get_trip_val(
2212         TRIP_FLOW,
2213         pdev->params.mtu,
2214         &val,
2215         pdev->vars.enable_cu_rate_limiter,
2216         mbuf_adj);
2217 
2218     REG_WR_IND(
2219             pdev,
2220             OFFSETOF(reg_space_t, rbuf.rbuf_config),
2221             val);
2222 
2223     get_trip_val(
2224         TRIP_MAC,
2225         pdev->params.mtu,
2226         &val,
2227         pdev->vars.enable_cu_rate_limiter,
2228         mbuf_adj);
2229 
2230     REG_WR_IND(
2231             pdev,
2232             OFFSETOF(reg_space_t, rbuf.rbuf_config2),
2233             val);
2234 
2235     if(!pdev->vars.enable_cu_rate_limiter)
2236     {
2237         get_trip_val(TRIP_CU, pdev->params.mtu, &val, 0, 0);
2238         REG_WR_IND(
2239             pdev,
2240             OFFSETOF(reg_space_t, rbuf.rbuf_config3),
2241             val);
2242     }
2243     else
2244     {
2245         /* isolate catchup traffic rbuf from normal traffic */
2246         REG_RD_IND(
2247             pdev,
2248             OFFSETOF(reg_space_t, rbuf.rbuf_command),
2249             &val);
2250         val |= RBUF_COMMAND_CU_ISOLATE_XI;
2251         REG_WR_IND(
2252             pdev,
2253             OFFSETOF(reg_space_t, rbuf.rbuf_command),
2254             val);
2255 
2256         REG_WR_IND(
2257                 pdev,
2258                 OFFSETOF(reg_space_t, rbuf.rbuf_config3),
2259                 0);
2260         if(pdev->vars.cu_mbuf_cnt)
2261         {
2262             val = pdev->vars.cu_mbuf_cnt;
2263             REG_WR_IND(
2264                 pdev,
2265                 OFFSETOF(reg_space_t, rbuf.rbuf_cu_buffer_size),
2266                 val);
2267         }
2268         else
2269         {
2270             /* get default cu_mbuf_cnt from chip */
2271             REG_RD_IND(
2272                 pdev,
2273                 OFFSETOF(reg_space_t, rbuf.rbuf_cu_buffer_size),
2274                 &val);
2275         }
2276         /*account for initial MBUF allocated by the RPC*/
2277         val -= 1;
2278         val *= 128;
2279         REG_WR_IND(
2280             pdev,
2281             OFFSETOF(reg_space_t, com.com_scratch[0])+COM_HSI_OFFSETOFF(com_cu_buf_size),
2282             val);
2283         REG_WR_IND(
2284             pdev,
2285             OFFSETOF(reg_space_t, com.com_scratch[0])+COM_HSI_OFFSETOFF(cu_rate_limiter_enable),
2286             1);
2287         REG_WR_IND(
2288             pdev,
2289             OFFSETOF(reg_space_t, txp.txp_scratch[0])+TXP_HSI_OFFSETOFF(cu_rate_limiter_enable),
2290             1);
2291         REG_WR_IND(
2292             pdev,
2293             OFFSETOF(reg_space_t, rxp.rxp_scratch[0])+RXP_HSI_OFFSETOFF(cu_rate_limiter_enable),
2294             1);
2295     }
2296 
2297     /* Set up how to generate a link change interrupt. */
2298     if(pdev->params.phy_int_mode == PHY_INT_MODE_MI_INTERRUPT)
2299     {
2300         REG_WR(pdev, emac.emac_attention_ena, EMAC_ATTENTION_ENA_MI_INT);
2301     }
2302     else if(pdev->params.phy_int_mode == PHY_INT_MODE_LINK_READY)
2303     {
2304         REG_WR(pdev, emac.emac_attention_ena, EMAC_ATTENTION_ENA_LINK);
2305     }
2306     else if(pdev->params.phy_int_mode == PHY_INT_MODE_AUTO_POLLING)
2307     {
2308         REG_WR(pdev, emac.emac_attention_ena, EMAC_ATTENTION_ENA_LINK);
2309 
2310         REG_RD(pdev, emac.emac_mdio_mode, &val);
2311         val |= EMAC_MDIO_MODE_AUTO_POLL;
2312         REG_WR(pdev, emac.emac_mdio_mode, val);
2313     }
2314     else
2315     {
2316         DbgBreakMsg("Invalid phy_int_mode.\n");
2317     }
2318 
2319     zero_out_sb(pdev, (u32_t *) pdev->vars.status_virt);
2320 
2321     if(CHIP_NUM(pdev) == CHIP_NUM_5706 ||
2322         CHIP_NUM(pdev) == CHIP_NUM_5708)
2323     {
2324         init_hc(pdev);
2325     }
2326     else if(CHIP_NUM(pdev) == CHIP_NUM_5709)
2327     {
2328         init_hc_for_5709(pdev);
2329     }
2330     else if(CHIP_NUM(pdev) == CHIP_NUM_57728)
2331     {
2332         init_hc_for_57728(pdev);
2333     }
2334     else
2335     {
2336         DbgBreakMsg("### Invalid chip number.\n");
2337     }
2338 
2339     if(CHIP_REV(pdev) == CHIP_REV_IKOS || CHIP_REV(pdev) == CHIP_REV_FPGA)
2340     {
2341         reduce_ftq_depth(pdev);
2342     }
2343 
2344     init_l2txq(pdev);
2345     init_l2rxq(pdev);
2346 
2347     #ifndef EXCLUDE_KQE_SUPPORT
2348     init_kq(pdev);
2349     #endif
2350 
2351     #if INCLUDE_OFLD_SUPPORT
2352     l4_reset_setup(pdev);
2353     #endif
2354 
2355     /* Enable Commnad Scheduler notification when we write to the
2356      * host producer index of the kernel contexts. */
2357     REG_WR(pdev, mq.mq_knl_cmd_mask1, KNL_L5_MASK(sq_pidx));
2358 
2359     /* Enable Command Scheduler notification when we write to either
2360      * the Send Queue or Receive Queue producer indexes of the kernel
2361      * bypass contexts. */
2362     REG_WR(pdev, mq.mq_knl_byp_cmd_mask1, KNL_L5_MASK(cq_cidx)|
2363                                           KNL_L5_MASK(sq_pidx)|
2364                                           KNL_L5_MASK(rq_pidx));
2365     REG_WR(pdev, mq.mq_knl_byp_write_mask1,  KNL_L5_MASK(cq_cidx)|
2366                                              KNL_L5_MASK(sq_pidx)|
2367                                              KNL_L5_MASK(rq_pidx));
2368 
2369     /* Use kernel mailbox for L5 context (iSCSI and rdma). */
2370     REG_WR(pdev, mq.mq_knl_cmd_mask1,   KNL_L5_MASK(cq_cidx)|
2371                                         KNL_L5_MASK(sq_pidx)|
2372                                         KNL_L5_MASK(rq_pidx));
2373     REG_WR(pdev, mq.mq_knl_write_mask1,  KNL_L5_MASK(cq_cidx)|
2374                                          KNL_L5_MASK(sq_pidx)|
2375                                          KNL_L5_MASK(rq_pidx));
2376 #ifndef L2_ONLY
2377     if(CHIP_NUM(pdev) != CHIP_NUM_5709)
2378     {
2379         /* Notify CP when the driver post an application buffer. (i.e. writing to host_bseq) */
2380         REG_WR(pdev, mq.mq_knl_cmd_mask2, KNL_L4_MASK(host_bseq));
2381     }
2382     else  // CHIP_NUM_5709
2383     {
2384         /* Notify RV2P when the driver post an application buffer. (i.e. writing to host_bseq) */
2385         REG_WR(pdev, mq.mq_knl_rx_v2p_mask2, KNL_L4_MASK(host_bseq));
2386     }
2387 #endif
2388     #ifndef EXCLUDE_KQE_SUPPORT
2389     /* fw_doorbell - These two processors polls the doorbell for a non zero
2390      * value before running.  This must be done after setting up the kernel
2391      * queue contexts. */
2392     if(pdev->params.kcq_page_cnt)
2393     {
2394         REG_WR_IND(pdev, OFFSETOF(reg_space_t, cp.cp_scratch[0])+CP_HSI_OFFSETOFF(fw_doorbell), 1);
2395         REG_WR_IND(pdev, OFFSETOF(reg_space_t, com.com_scratch[0])+COM_HSI_OFFSETOFF(fw_doorbell), 1);
2396 
2397         mm_wait(pdev, 5);
2398     }
2399     #endif
2400 
2401     /* get information from firmware-configured mq.mq_config2. */
2402     if(pdev->params.bin_mq_mode)
2403     {
2404         REG_RD(pdev, mq.mq_config2, &val);
2405 
2406         pdev->hw_info.first_l4_l5_bin = (u16_t) (val & MQ_CONFIG2_FIRST_L4L5);
2407         pdev->hw_info.bin_size = (u8_t) (val & MQ_CONFIG2_CONT_SZ) >> 3;
2408     }
2409 
2410     /* Configure page size and start the RV2P processors. */
2411     val = (LM_PAGE_BITS - 8) << 24;
2412     REG_WR(pdev, rv2p.rv2p_config, val);
2413 
2414     /* Setup the MAC for the current link settings.  The HC should be already
2415      * enabled.  We need to enable it so it is aware of the current link
2416      * state and link acknowledgement (via the call below).  The first
2417      * status block update we get will reflect the current link state. */
2418     lm_service_phy_int(pdev, TRUE);
2419 
2420     return LM_STATUS_SUCCESS;
2421 } /* lm_reset_setup */
2422 
2423 
2424 
2425 #if INCLUDE_OFLD_SUPPORT
2426 /*******************************************************************************
2427  * Description:
2428  *
2429  * Return:
2430  ******************************************************************************/
2431 STATIC void
2432 enable_alt_catchup(
2433     lm_device_t *pdev)
2434 {
2435     l4_kwqe_enable_alt_catchup_t *alt_catchup_kwqe;
2436     kwqe_t *prod_qe;
2437     u16_t prod_idx;
2438 
2439     pdev->kq_info.kwqe_left -= 1;
2440 
2441     prod_qe = pdev->kq_info.kwq_prod_qe;
2442     prod_idx = pdev->kq_info.kwq_prod_idx;
2443 
2444     alt_catchup_kwqe = (l4_kwqe_enable_alt_catchup_t *) prod_qe;
2445     alt_catchup_kwqe->tcp_hdr_flags = TCP_HDR_FLAGS_LAYER_MASK_L4;
2446     alt_catchup_kwqe->tcp_hdr_opcode = TCP_HDR_OPCODE_VALUE_ENABLE_ALT_CATCHUP;
2447 
2448     /* Advance to the next KWQE. */
2449     if(prod_qe == pdev->kq_info.kwq_last_qe)
2450     {
2451         prod_qe = pdev->kq_info.kwq_virt;
2452     }
2453     else
2454     {
2455         prod_qe++;
2456     }
2457     prod_idx++;
2458 
2459     pdev->kq_info.kwq_prod_qe = prod_qe;
2460     pdev->kq_info.kwq_prod_idx = prod_idx;
2461 
2462     /* catchup_override - use cid 0x30 (catchup2) instead of tx1 for catcup. */
2463     REG_WR_IND(
2464             pdev,
2465             OFFSETOF(reg_space_t, tpat.tpat_scratch[0])+TPAT_HSI_OFFSETOFF(catchup_overide),
2466             1);
2467 
2468     MBQ_WR16(
2469         pdev,
2470         GET_CID(pdev->kq_info.kwq_cid_addr),
2471         OFFSETOF(krnlq_context_t, krnlq_host_qidx),
2472         prod_idx);
2473 } /* enable_alt_catchup */
2474 #endif
2475 
2476 
2477 
2478 /*******************************************************************************
2479  * Description:
2480  *
2481  * Return:
2482  ******************************************************************************/
2483 lm_status_t
2484 lm_reset_run(
2485     lm_device_t *pdev)
2486 {
2487     u32_t max_loop_cnt;
2488     u32_t idx;
2489 
2490     /* Enable all the state machines including the processors. We could use
2491      * REG_WR(pdev, misc.misc_command, MISC_COMMAND_ENABLE_ALL) this write
2492      * but for now we don't want to enable the timer block yet.  This
2493      * needs to be done by the firmware. */
2494     REG_WR(pdev, misc.misc_enable_set_bits, 0x15ffffff);
2495 
2496     /* Allow the firmware to run.  How long is the delay? */
2497     max_loop_cnt = 1000;
2498     if(CHIP_REV(pdev) == CHIP_REV_IKOS)
2499     {
2500         max_loop_cnt = 25000;
2501     }
2502 
2503     for(idx = 0; idx < max_loop_cnt; idx++)
2504     {
2505         mm_wait(pdev, 10);
2506     }
2507 
2508     #if INCLUDE_OFLD_SUPPORT
2509     /* 'tx4' (cid 30/31) for catcup. */
2510     if(pdev->tx_info.cu_idx != TX_CHAIN_IDX1)
2511     {
2512         enable_alt_catchup(pdev);
2513     }
2514     #endif
2515 
2516     /* Force the first status block update so we can acknowledge the initial
2517      * link status and service an link change since we last call
2518      * lm_service_phy_int.  If we need to do this here so that we don't have
2519      * to service a link change event when later we receive a status
2520      * block update. */
2521     REG_WR(pdev, hc.hc_command, HC_COMMAND_COAL_NOW_WO_INT);
2522 
2523     /* Wait for the status block.  In the IKOS environment we need to
2524      * wait this long.  This delay may be reduced significantly when running
2525      * on the real chip. */
2526     mm_wait(pdev, 20);
2527     if(CHIP_REV(pdev) == CHIP_REV_IKOS)
2528     {
2529         for(idx = 0; idx < 100; idx++)
2530         {
2531             mm_wait(pdev, 10);
2532         }
2533     }
2534 
2535     /* Setup the MAC for the current link settings and acknowledge the
2536      * current link state if necessary. */
2537     lm_service_phy_int(pdev, FALSE);
2538 
2539     /* Ensure the status block in host memory reflect the current link
2540      * state and link acknowledgement. */
2541     REG_WR(pdev, hc.hc_command, HC_COMMAND_COAL_NOW);
2542 
2543     return LM_STATUS_SUCCESS;
2544 } /* lm_reset_run */
2545 
2546 
2547 
2548 /*******************************************************************************
2549  * Description:
2550  *
2551  * Return:
2552  ******************************************************************************/
2553 lm_status_t
2554 lm_reset(
2555     lm_device_t *pdev,
2556     u32_t reset_reason)
2557 {
2558     lm_status_t status;
2559 
2560     status = lm_reset_setup(pdev, reset_reason);
2561     if(status == LM_STATUS_SUCCESS)
2562     {
2563         status = lm_reset_run(pdev);
2564     }
2565 
2566     return status;
2567 } /* lm_reset */
2568