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