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 #include "lm5706.h"
16eef4f27bSRobert Mustacchi #if !defined(LINUX) && !defined(SOLARIS)
17eef4f27bSRobert Mustacchi #include "string.h"     // needed by some OS for memset
18eef4f27bSRobert Mustacchi #pragma warning(disable:28718)
19eef4f27bSRobert Mustacchi #endif
20eef4f27bSRobert Mustacchi 
21eef4f27bSRobert Mustacchi 
22eef4f27bSRobert Mustacchi /*******************************************************************************
23eef4f27bSRobert Mustacchi  * Description:
24eef4f27bSRobert Mustacchi  *
25eef4f27bSRobert Mustacchi  * Return:
26eef4f27bSRobert Mustacchi  ******************************************************************************/
27eef4f27bSRobert Mustacchi void
lm_abort(lm_device_t * pdev,u32_t abort_op,u32_t idx)28eef4f27bSRobert Mustacchi lm_abort(
29eef4f27bSRobert Mustacchi     lm_device_t *pdev,
30eef4f27bSRobert Mustacchi     u32_t abort_op,
31eef4f27bSRobert Mustacchi     u32_t idx)
32eef4f27bSRobert Mustacchi {
33eef4f27bSRobert Mustacchi     if(abort_op == ABORT_OP_RX_CHAIN)
34eef4f27bSRobert Mustacchi     {
35eef4f27bSRobert Mustacchi         lm_recv_abort(pdev, idx);
36eef4f27bSRobert Mustacchi     }
37eef4f27bSRobert Mustacchi     else if(abort_op == ABORT_OP_TX_CHAIN)
38eef4f27bSRobert Mustacchi     {
39eef4f27bSRobert Mustacchi         lm_send_abort(pdev, idx);
40eef4f27bSRobert Mustacchi     }
41eef4f27bSRobert Mustacchi     else
42eef4f27bSRobert Mustacchi     {
43eef4f27bSRobert Mustacchi         DbgBreakMsg("Invalid abort.\n");
44eef4f27bSRobert Mustacchi     }
45eef4f27bSRobert Mustacchi } /* lm_abort */
46eef4f27bSRobert Mustacchi 
47eef4f27bSRobert Mustacchi 
48eef4f27bSRobert Mustacchi 
49eef4f27bSRobert Mustacchi /*******************************************************************************
50eef4f27bSRobert Mustacchi  * Description:
51eef4f27bSRobert Mustacchi  *
52eef4f27bSRobert Mustacchi  * Return:
53eef4f27bSRobert Mustacchi  ******************************************************************************/
54eef4f27bSRobert Mustacchi STATIC char *
val_to_decimal_string(char * str_buf,u32_t buf_size,u32_t val)55eef4f27bSRobert Mustacchi val_to_decimal_string(
56eef4f27bSRobert Mustacchi     char *str_buf,
57eef4f27bSRobert Mustacchi     u32_t buf_size,
58eef4f27bSRobert Mustacchi     u32_t val)
59eef4f27bSRobert Mustacchi {
60eef4f27bSRobert Mustacchi     u32_t digit;
61eef4f27bSRobert Mustacchi 
62eef4f27bSRobert Mustacchi     if(buf_size == 0)
63eef4f27bSRobert Mustacchi     {
64eef4f27bSRobert Mustacchi         return str_buf;
65eef4f27bSRobert Mustacchi     }
66eef4f27bSRobert Mustacchi 
67eef4f27bSRobert Mustacchi     digit = val % 10;
68eef4f27bSRobert Mustacchi     val = val / 10;
69eef4f27bSRobert Mustacchi 
70eef4f27bSRobert Mustacchi     if(val)
71eef4f27bSRobert Mustacchi     {
72eef4f27bSRobert Mustacchi         buf_size--;
73eef4f27bSRobert Mustacchi         str_buf = val_to_decimal_string(str_buf, buf_size, val);
74eef4f27bSRobert Mustacchi     }
75eef4f27bSRobert Mustacchi 
76eef4f27bSRobert Mustacchi     *str_buf = '0' + digit;
77eef4f27bSRobert Mustacchi 
78eef4f27bSRobert Mustacchi     str_buf++;
79eef4f27bSRobert Mustacchi 
80eef4f27bSRobert Mustacchi     return str_buf;
81eef4f27bSRobert Mustacchi } /* val_to_decimal_string */
82eef4f27bSRobert Mustacchi 
83eef4f27bSRobert Mustacchi 
84eef4f27bSRobert Mustacchi 
85eef4f27bSRobert Mustacchi /*******************************************************************************
86eef4f27bSRobert Mustacchi  * Description:
87eef4f27bSRobert Mustacchi  *
88eef4f27bSRobert Mustacchi  * Return:
89eef4f27bSRobert Mustacchi  ******************************************************************************/
90eef4f27bSRobert Mustacchi STATIC u32_t
build_ver_string(char * str_buf,u32_t buf_size,u8_t major_ver,u8_t minor_ver,u8_t rel_num,u8_t fix_num)91eef4f27bSRobert Mustacchi build_ver_string(
92eef4f27bSRobert Mustacchi     char *str_buf,
93eef4f27bSRobert Mustacchi     u32_t buf_size,
94eef4f27bSRobert Mustacchi     u8_t major_ver,
95eef4f27bSRobert Mustacchi     u8_t minor_ver,
96eef4f27bSRobert Mustacchi     u8_t rel_num,
97eef4f27bSRobert Mustacchi     u8_t fix_num)
98eef4f27bSRobert Mustacchi {
99eef4f27bSRobert Mustacchi     char *p;
100eef4f27bSRobert Mustacchi 
101eef4f27bSRobert Mustacchi     if(buf_size == 0)
102eef4f27bSRobert Mustacchi     {
103eef4f27bSRobert Mustacchi         return 0;
104eef4f27bSRobert Mustacchi     }
105eef4f27bSRobert Mustacchi 
106eef4f27bSRobert Mustacchi     p = str_buf;
107eef4f27bSRobert Mustacchi 
108eef4f27bSRobert Mustacchi     if(buf_size - (p - str_buf) > 1)
109eef4f27bSRobert Mustacchi     {
110eef4f27bSRobert Mustacchi         *p = 'v';
111eef4f27bSRobert Mustacchi         p++;
112eef4f27bSRobert Mustacchi     }
113eef4f27bSRobert Mustacchi 
114eef4f27bSRobert Mustacchi     if(buf_size - (p - str_buf) > 1)
115eef4f27bSRobert Mustacchi     {
116eef4f27bSRobert Mustacchi         p = val_to_decimal_string(
117eef4f27bSRobert Mustacchi             p,
118eef4f27bSRobert Mustacchi             buf_size - (u32_t) PTR_SUB(p, str_buf),
119eef4f27bSRobert Mustacchi             major_ver);
120eef4f27bSRobert Mustacchi     }
121eef4f27bSRobert Mustacchi 
122eef4f27bSRobert Mustacchi     if(buf_size - (p - str_buf) > 1)
123eef4f27bSRobert Mustacchi     {
124eef4f27bSRobert Mustacchi         *p = '.';
125eef4f27bSRobert Mustacchi         p++;
126eef4f27bSRobert Mustacchi     }
127eef4f27bSRobert Mustacchi 
128eef4f27bSRobert Mustacchi     if(buf_size - (u32_t) PTR_SUB(p, str_buf) > 1)
129eef4f27bSRobert Mustacchi     {
130eef4f27bSRobert Mustacchi         p = val_to_decimal_string(
131eef4f27bSRobert Mustacchi             p,
132eef4f27bSRobert Mustacchi             buf_size - (u32_t) PTR_SUB(p, str_buf),
133eef4f27bSRobert Mustacchi             minor_ver);
134eef4f27bSRobert Mustacchi     }
135eef4f27bSRobert Mustacchi 
136eef4f27bSRobert Mustacchi     if(buf_size - (u32_t) PTR_SUB(p, str_buf) > 1)
137eef4f27bSRobert Mustacchi     {
138eef4f27bSRobert Mustacchi         *p = '.';
139eef4f27bSRobert Mustacchi         p++;
140eef4f27bSRobert Mustacchi     }
141eef4f27bSRobert Mustacchi 
142eef4f27bSRobert Mustacchi     if(buf_size - (u32_t) PTR_SUB(p, str_buf) > 1)
143eef4f27bSRobert Mustacchi     {
144eef4f27bSRobert Mustacchi         p = val_to_decimal_string(
145eef4f27bSRobert Mustacchi             p,
146eef4f27bSRobert Mustacchi             buf_size - (u32_t) PTR_SUB(p, str_buf),
147eef4f27bSRobert Mustacchi             rel_num);
148eef4f27bSRobert Mustacchi     }
149eef4f27bSRobert Mustacchi 
150eef4f27bSRobert Mustacchi     if(buf_size - (u32_t) PTR_SUB(p, str_buf) > 1)
151eef4f27bSRobert Mustacchi     {
152eef4f27bSRobert Mustacchi         *p = '.';
153eef4f27bSRobert Mustacchi         p++;
154eef4f27bSRobert Mustacchi     }
155*55fea89dSDan Cross 
156eef4f27bSRobert Mustacchi     if(buf_size - (u32_t) PTR_SUB(p, str_buf) > 1)
157eef4f27bSRobert Mustacchi     {
158eef4f27bSRobert Mustacchi         p = val_to_decimal_string(
159eef4f27bSRobert Mustacchi             p,
160eef4f27bSRobert Mustacchi             buf_size - (u32_t) PTR_SUB(p, str_buf),
161eef4f27bSRobert Mustacchi             fix_num);
162eef4f27bSRobert Mustacchi     }
163eef4f27bSRobert Mustacchi 
164eef4f27bSRobert Mustacchi     if(buf_size - (u32_t) PTR_SUB(p, str_buf) > 1)
165eef4f27bSRobert Mustacchi     {
166eef4f27bSRobert Mustacchi         *p = '.';
167eef4f27bSRobert Mustacchi         p++;
168eef4f27bSRobert Mustacchi     }
169eef4f27bSRobert Mustacchi 
170eef4f27bSRobert Mustacchi     if(buf_size - (u32_t) PTR_SUB(p, str_buf) > 1)
171eef4f27bSRobert Mustacchi     {
172eef4f27bSRobert Mustacchi         #if DBG
173eef4f27bSRobert Mustacchi         *p = 'd';
174eef4f27bSRobert Mustacchi         #else
175eef4f27bSRobert Mustacchi         *p = 'r';
176eef4f27bSRobert Mustacchi         #endif
177eef4f27bSRobert Mustacchi 
178eef4f27bSRobert Mustacchi         p++;
179eef4f27bSRobert Mustacchi     }
180eef4f27bSRobert Mustacchi 
181eef4f27bSRobert Mustacchi     if(buf_size - (u32_t) PTR_SUB(p, str_buf) > 1)
182eef4f27bSRobert Mustacchi     {
183eef4f27bSRobert Mustacchi         #if DBG
184eef4f27bSRobert Mustacchi         *p = 'b';
185eef4f27bSRobert Mustacchi         #else
186eef4f27bSRobert Mustacchi         *p = 't';
187eef4f27bSRobert Mustacchi         #endif
188eef4f27bSRobert Mustacchi 
189eef4f27bSRobert Mustacchi         p++;
190eef4f27bSRobert Mustacchi     }
191eef4f27bSRobert Mustacchi 
192eef4f27bSRobert Mustacchi     if(buf_size - (u32_t) PTR_SUB(p, str_buf) > 1)
193eef4f27bSRobert Mustacchi     {
194eef4f27bSRobert Mustacchi         #if DBG
195eef4f27bSRobert Mustacchi         *p = 'g';
196eef4f27bSRobert Mustacchi         #else
197eef4f27bSRobert Mustacchi         *p = 'l';
198eef4f27bSRobert Mustacchi         #endif
199eef4f27bSRobert Mustacchi 
200eef4f27bSRobert Mustacchi         p++;
201eef4f27bSRobert Mustacchi     }
202eef4f27bSRobert Mustacchi 
203eef4f27bSRobert Mustacchi     *p = 0;
204eef4f27bSRobert Mustacchi     p++;
205eef4f27bSRobert Mustacchi 
206eef4f27bSRobert Mustacchi     return (u32_t) PTR_SUB(p, str_buf);
207eef4f27bSRobert Mustacchi } /* build_ver_string */
208eef4f27bSRobert Mustacchi 
209eef4f27bSRobert Mustacchi 
210eef4f27bSRobert Mustacchi 
211eef4f27bSRobert Mustacchi /*******************************************************************************
212eef4f27bSRobert Mustacchi  * Description:
213eef4f27bSRobert Mustacchi  *
214eef4f27bSRobert Mustacchi  * Return:
215eef4f27bSRobert Mustacchi  ******************************************************************************/
216eef4f27bSRobert Mustacchi STATIC void
get_max_conns(lm_device_t * pdev,u32_t * max_toe_conn,u32_t * max_iscsi_conn,u32_t * max_iscsi_pending_tasks)217eef4f27bSRobert Mustacchi get_max_conns(
218eef4f27bSRobert Mustacchi     lm_device_t *pdev,
219eef4f27bSRobert Mustacchi     u32_t *max_toe_conn,
220eef4f27bSRobert Mustacchi     u32_t *max_iscsi_conn,
221eef4f27bSRobert Mustacchi     u32_t *max_iscsi_pending_tasks)
222eef4f27bSRobert Mustacchi {
223eef4f27bSRobert Mustacchi     u32_t max_lic_conn;
224eef4f27bSRobert Mustacchi     u32_t max_res_conn;
225eef4f27bSRobert Mustacchi     u32_t res_flags;
226eef4f27bSRobert Mustacchi 
227eef4f27bSRobert Mustacchi     /* get resource reservation flag. */
228eef4f27bSRobert Mustacchi     REG_RD_IND(
229eef4f27bSRobert Mustacchi         pdev,
230eef4f27bSRobert Mustacchi         pdev->hw_info.shmem_base +
231eef4f27bSRobert Mustacchi             OFFSETOF(shmem_region_t,
232eef4f27bSRobert Mustacchi                 dev_info.port_feature_config.resource.res_cfg),
233eef4f27bSRobert Mustacchi         &res_flags);
234eef4f27bSRobert Mustacchi 
235eef4f27bSRobert Mustacchi     /* get max_lic_conn for toe. */
236eef4f27bSRobert Mustacchi     REG_RD_IND(
237eef4f27bSRobert Mustacchi         pdev,
238eef4f27bSRobert Mustacchi         pdev->hw_info.shmem_base +
239eef4f27bSRobert Mustacchi             OFFSETOF(shmem_region_t, fw_lic_key.max_toe_conn),
240eef4f27bSRobert Mustacchi         &max_lic_conn);
241eef4f27bSRobert Mustacchi 
242eef4f27bSRobert Mustacchi     max_lic_conn &= 0xffff;
243eef4f27bSRobert Mustacchi 
244eef4f27bSRobert Mustacchi     if(max_lic_conn)
245eef4f27bSRobert Mustacchi     {
246eef4f27bSRobert Mustacchi         max_lic_conn ^= FW_ENCODE_16BIT_PATTERN;
247eef4f27bSRobert Mustacchi 
248eef4f27bSRobert Mustacchi         if(max_lic_conn == 0xffff)
249eef4f27bSRobert Mustacchi         {
250eef4f27bSRobert Mustacchi             max_lic_conn = 1024;
251eef4f27bSRobert Mustacchi         }
252eef4f27bSRobert Mustacchi     }
253eef4f27bSRobert Mustacchi 
254eef4f27bSRobert Mustacchi     /* get max_res_conn for toe. */
255eef4f27bSRobert Mustacchi     if(res_flags & RES_RES_CFG_VALID)
256eef4f27bSRobert Mustacchi     {
257eef4f27bSRobert Mustacchi         if(res_flags & RES_RES_CFG_L2)
258eef4f27bSRobert Mustacchi         {
259eef4f27bSRobert Mustacchi             REG_RD_IND(
260eef4f27bSRobert Mustacchi                 pdev,
261eef4f27bSRobert Mustacchi                 pdev->hw_info.shmem_base +
262eef4f27bSRobert Mustacchi                     OFFSETOF(shmem_region_t,
263eef4f27bSRobert Mustacchi                         dev_info.port_feature_config.resource.conn_resource1),
264eef4f27bSRobert Mustacchi                 &max_res_conn);
265eef4f27bSRobert Mustacchi             /*
266eef4f27bSRobert Mustacchi              * if(max_res_conn == 0 || !(res_flags & RES_RES_CFG_FCFS_DISABLED))
267eef4f27bSRobert Mustacchi              * CQ#42214 HH, SK and HYF all agreed on removing the test
268eef4f27bSRobert Mustacchi              * for max_res_conn == 0
269eef4f27bSRobert Mustacchi              */
270eef4f27bSRobert Mustacchi             if (!(res_flags & RES_RES_CFG_FCFS_DISABLED))
271eef4f27bSRobert Mustacchi             {
272eef4f27bSRobert Mustacchi                 max_res_conn = 1024;
273eef4f27bSRobert Mustacchi             }
274eef4f27bSRobert Mustacchi         }
275eef4f27bSRobert Mustacchi         else
276eef4f27bSRobert Mustacchi         {
277eef4f27bSRobert Mustacchi             max_res_conn = 0;
278eef4f27bSRobert Mustacchi         }
279eef4f27bSRobert Mustacchi     }
280eef4f27bSRobert Mustacchi     else
281eef4f27bSRobert Mustacchi     {
282eef4f27bSRobert Mustacchi         max_res_conn = 1024;
283eef4f27bSRobert Mustacchi     }
284eef4f27bSRobert Mustacchi 
285eef4f27bSRobert Mustacchi     *max_toe_conn = (max_lic_conn < max_res_conn) ? max_lic_conn: max_res_conn;
286eef4f27bSRobert Mustacchi 
287eef4f27bSRobert Mustacchi     /* get iscsi pending tasks. */
288eef4f27bSRobert Mustacchi     if((res_flags & RES_RES_CFG_VALID) && (res_flags & RES_RES_CFG_ISCSI))
289eef4f27bSRobert Mustacchi     {
290eef4f27bSRobert Mustacchi         REG_RD_IND(
291eef4f27bSRobert Mustacchi             pdev,
292eef4f27bSRobert Mustacchi             pdev->hw_info.shmem_base +
293eef4f27bSRobert Mustacchi                 OFFSETOF(shmem_region_t,
294eef4f27bSRobert Mustacchi                     dev_info.port_feature_config.resource.conn_resource3),
295eef4f27bSRobert Mustacchi             max_iscsi_pending_tasks);
296eef4f27bSRobert Mustacchi 
297eef4f27bSRobert Mustacchi         *max_iscsi_pending_tasks &= RES_CONN_ISCSI_PTASK_MASK;
298eef4f27bSRobert Mustacchi 
299eef4f27bSRobert Mustacchi         if(*max_iscsi_pending_tasks == 0 || *max_iscsi_pending_tasks > 128)
300eef4f27bSRobert Mustacchi         {
301eef4f27bSRobert Mustacchi             *max_iscsi_pending_tasks = 128;
302eef4f27bSRobert Mustacchi         }
303eef4f27bSRobert Mustacchi     }
304eef4f27bSRobert Mustacchi     else
305eef4f27bSRobert Mustacchi     {
306eef4f27bSRobert Mustacchi         *max_iscsi_pending_tasks = 128;
307eef4f27bSRobert Mustacchi         *max_iscsi_conn = 0;
308eef4f27bSRobert Mustacchi     }
309eef4f27bSRobert Mustacchi 
310eef4f27bSRobert Mustacchi     REG_RD_IND(
311eef4f27bSRobert Mustacchi         pdev,
312eef4f27bSRobert Mustacchi         pdev->hw_info.shmem_base +
313eef4f27bSRobert Mustacchi             OFFSETOF(shmem_region_t, fw_lic_key.max_iscsi_trgt_conn),
314eef4f27bSRobert Mustacchi         &max_lic_conn);
315eef4f27bSRobert Mustacchi 
316eef4f27bSRobert Mustacchi     if(max_lic_conn)
317eef4f27bSRobert Mustacchi     {
318eef4f27bSRobert Mustacchi         max_lic_conn ^= FW_ENCODE_32BIT_PATTERN;
319eef4f27bSRobert Mustacchi         max_lic_conn >>= 16;
320eef4f27bSRobert Mustacchi     }
321eef4f27bSRobert Mustacchi 
322eef4f27bSRobert Mustacchi     *max_iscsi_conn = max_lic_conn;
323eef4f27bSRobert Mustacchi 
324eef4f27bSRobert Mustacchi     /* no license information. */
325eef4f27bSRobert Mustacchi     if(*max_toe_conn == 0)
326eef4f27bSRobert Mustacchi     {
327eef4f27bSRobert Mustacchi         if(pdev->hw_info.svid == 0x103c)        /* HP device. */
328eef4f27bSRobert Mustacchi         {
329eef4f27bSRobert Mustacchi             *max_toe_conn = 1024;
330eef4f27bSRobert Mustacchi         }
331eef4f27bSRobert Mustacchi         else if(CHIP_REV(pdev) == CHIP_REV_IKOS ||
332eef4f27bSRobert Mustacchi                 CHIP_REV(pdev) == CHIP_REV_FPGA)
333eef4f27bSRobert Mustacchi         {
334eef4f27bSRobert Mustacchi             *max_toe_conn = 32;
335eef4f27bSRobert Mustacchi         }
336eef4f27bSRobert Mustacchi     }
337eef4f27bSRobert Mustacchi 
338eef4f27bSRobert Mustacchi     /* cq#39856 - iSCSI Device Disappears from System after reboot. */
339eef4f27bSRobert Mustacchi     if(*max_iscsi_conn == 0)
340eef4f27bSRobert Mustacchi     {
341eef4f27bSRobert Mustacchi         if(pdev->hw_info.svid == 0x103c)        /* HP device. */
342eef4f27bSRobert Mustacchi         {
343eef4f27bSRobert Mustacchi             *max_iscsi_conn = 1024;
344eef4f27bSRobert Mustacchi         }
345eef4f27bSRobert Mustacchi         else if(CHIP_REV(pdev) == CHIP_REV_IKOS ||
346eef4f27bSRobert Mustacchi                 CHIP_REV(pdev) == CHIP_REV_FPGA)
347eef4f27bSRobert Mustacchi         {
348eef4f27bSRobert Mustacchi             *max_iscsi_conn = 32;
349eef4f27bSRobert Mustacchi         }
350eef4f27bSRobert Mustacchi     }
351eef4f27bSRobert Mustacchi } /* get_max_conns */
352eef4f27bSRobert Mustacchi 
353eef4f27bSRobert Mustacchi 
354eef4f27bSRobert Mustacchi 
355eef4f27bSRobert Mustacchi /*******************************************************************************
356eef4f27bSRobert Mustacchi  * Description:
357eef4f27bSRobert Mustacchi  *
358eef4f27bSRobert Mustacchi  * Return:
359eef4f27bSRobert Mustacchi  ******************************************************************************/
360eef4f27bSRobert Mustacchi lm_status_t
lm_get_dev_info(lm_device_t * pdev)361eef4f27bSRobert Mustacchi lm_get_dev_info(
362eef4f27bSRobert Mustacchi     lm_device_t *pdev)
363eef4f27bSRobert Mustacchi {
364eef4f27bSRobert Mustacchi     typedef struct _param_entry_t
365eef4f27bSRobert Mustacchi     {
366eef4f27bSRobert Mustacchi         /* Ideally, we want to save the address of the parameter here.
367eef4f27bSRobert Mustacchi          * However, some compiler will not allow us to dynamically
368eef4f27bSRobert Mustacchi          * initialize the pointer to a parameter in the table below.
369eef4f27bSRobert Mustacchi          * As an alternative, we will save the offset to the parameter
370eef4f27bSRobert Mustacchi          * from pdev device structure. */
371eef4f27bSRobert Mustacchi         u32_t offset;
372eef4f27bSRobert Mustacchi 
373eef4f27bSRobert Mustacchi         /* Parameter default value. */
374eef4f27bSRobert Mustacchi         u32_t asic_default;
375eef4f27bSRobert Mustacchi         u32_t fpga_ikos_default;
376eef4f27bSRobert Mustacchi 
377eef4f27bSRobert Mustacchi         /* Limit checking is diabled if min and max are zeros. */
378eef4f27bSRobert Mustacchi         u32_t min;
379eef4f27bSRobert Mustacchi         u32_t max;
380eef4f27bSRobert Mustacchi     } param_entry_t;
381eef4f27bSRobert Mustacchi 
382eef4f27bSRobert Mustacchi     #define _OFFSET(_name)          (OFFSETOF(lm_device_t, params._name))
383eef4f27bSRobert Mustacchi     #define PARAM_VAL(_pdev, _entry) \
384eef4f27bSRobert Mustacchi         (*((u32_t *) ((u8_t *) (_pdev) + (_entry)->offset)))
385eef4f27bSRobert Mustacchi     #define SET_PARAM_VAL(_pdev, _entry, _val) \
386eef4f27bSRobert Mustacchi         *((u32_t *) ((u8_t *) (_pdev) + (_entry)->offset)) = (_val)
387eef4f27bSRobert Mustacchi 
388eef4f27bSRobert Mustacchi     static param_entry_t param_list[] =
389eef4f27bSRobert Mustacchi     {
390eef4f27bSRobert Mustacchi         /*                                 asic     fpga/ikos
391eef4f27bSRobert Mustacchi            offset                          default  default  min     max */
392eef4f27bSRobert Mustacchi         { _OFFSET(mtu),                    1500,    1500,    1500,   9018 },
393eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_desc_cnt[0]),      200,     150,     0,      0 },
394eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_desc_cnt[1]),      0,       0,       0,      0 },
395eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_desc_cnt[2]),      0,       0,       0,      0 },
396eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_desc_cnt[3]),      0,       0,       0,      0 },
397eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_desc_cnt[4]),      0,       0,       0,      0 },
398eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_desc_cnt[5]),      0,       0,       0,      0 },
399eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_desc_cnt[6]),      0,       0,       0,      0 },
400eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_desc_cnt[7]),      0,       0,       0,      0 },
401eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_desc_cnt[8]),      0,       0,       0,      0 },
402eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_desc_cnt[9]),      0,       0,       0,      0 },
403eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_desc_cnt[10]),     0,       0,       0,      0 },
404eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_desc_cnt[11]),     0,       0,       0,      0 },
405eef4f27bSRobert Mustacchi         #if 0
406eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_desc_cnt[12]),     0,       0,       0,      0 },
407eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_desc_cnt[13]),     0,       0,       0,      0 },
408eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_desc_cnt[14]),     0,       0,       0,      0 },
409eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_desc_cnt[15]),     0,       0,       0,      0 },
410eef4f27bSRobert Mustacchi         #endif
411eef4f27bSRobert Mustacchi 
412eef4f27bSRobert Mustacchi         /* The maximum page count is chosen to prevent us from having
413eef4f27bSRobert Mustacchi          * more than 32767 pending entries at any one time. */
414eef4f27bSRobert Mustacchi         { _OFFSET(l2_tx_bd_page_cnt[0]),   2,       2,       1,      127 },
415eef4f27bSRobert Mustacchi         { _OFFSET(l2_tx_bd_page_cnt[1]),   1,       1,       1,      127 },
416eef4f27bSRobert Mustacchi         { _OFFSET(l2_tx_bd_page_cnt[2]),   1,       1,       1,      127 },
417eef4f27bSRobert Mustacchi         { _OFFSET(l2_tx_bd_page_cnt[3]),   1,       1,       1,      127 },
418eef4f27bSRobert Mustacchi         { _OFFSET(l2_tx_bd_page_cnt[4]),   1,       1,       1,      127 },
419eef4f27bSRobert Mustacchi         { _OFFSET(l2_tx_bd_page_cnt[5]),   1,       1,       1,      127 },
420eef4f27bSRobert Mustacchi         { _OFFSET(l2_tx_bd_page_cnt[6]),   1,       1,       1,      127 },
421eef4f27bSRobert Mustacchi         { _OFFSET(l2_tx_bd_page_cnt[7]),   1,       1,       1,      127 },
422eef4f27bSRobert Mustacchi         { _OFFSET(l2_tx_bd_page_cnt[8]),   1,       1,       1,      127 },
423eef4f27bSRobert Mustacchi         { _OFFSET(l2_tx_bd_page_cnt[9]),   1,       1,       1,      127 },
424eef4f27bSRobert Mustacchi         { _OFFSET(l2_tx_bd_page_cnt[10]),  1,       1,       1,      127 },
425eef4f27bSRobert Mustacchi         { _OFFSET(l2_tx_bd_page_cnt[11]),  1,       1,       1,      127 },
426eef4f27bSRobert Mustacchi 
427eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_bd_page_cnt[0]),   2,       2,       1,      127 },
428eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_bd_page_cnt[1]),   1,       1,       1,      127 },
429eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_bd_page_cnt[2]),   1,       1,       1,      127 },
430eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_bd_page_cnt[3]),   1,       1,       1,      127 },
431eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_bd_page_cnt[4]),   1,       1,       1,      127 },
432eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_bd_page_cnt[5]),   1,       1,       1,      127 },
433eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_bd_page_cnt[6]),   1,       1,       1,      127 },
434eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_bd_page_cnt[7]),   1,       1,       1,      127 },
435eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_bd_page_cnt[8]),   1,       1,       1,      127 },
436eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_bd_page_cnt[9]),   1,       1,       1,      127 },
437eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_bd_page_cnt[10]),  1,       1,       1,      127 },
438eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_bd_page_cnt[11]),  1,       1,       1,      127 },
439eef4f27bSRobert Mustacchi         #if 0
440eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_bd_page_cnt[12]),  1,       1,       1,      127 },
441eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_bd_page_cnt[13]),  1,       1,       1,      127 },
442eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_bd_page_cnt[14]),  1,       1,       1,      127 },
443eef4f27bSRobert Mustacchi         { _OFFSET(l2_rx_bd_page_cnt[15]),  1,       1,       1,      127 },
444eef4f27bSRobert Mustacchi         #endif
445eef4f27bSRobert Mustacchi 
446eef4f27bSRobert Mustacchi         { _OFFSET(l4_tx_bd_page_cnt),      1,       1,       1,      255 },
447eef4f27bSRobert Mustacchi         { _OFFSET(limit_l4_tx_bd_cnt),     0,       0,       0,      0 },
448eef4f27bSRobert Mustacchi         { _OFFSET(l4_rx_bd_page_cnt),      1,       1,       1,      255 },
449eef4f27bSRobert Mustacchi         { _OFFSET(limit_l4_rx_bd_cnt),     0,       0,       0,      0 },
450eef4f27bSRobert Mustacchi 
451eef4f27bSRobert Mustacchi         #ifndef EXCLUDE_KQE_SUPPORT
452eef4f27bSRobert Mustacchi         #if INCLUDE_OFLD_SUPPORT
453eef4f27bSRobert Mustacchi         { _OFFSET(kwq_page_cnt),           4,       2,       1,      255 },
454eef4f27bSRobert Mustacchi         { _OFFSET(kcq_page_cnt),           32,      32,      1,      255 },
455eef4f27bSRobert Mustacchi         { _OFFSET(kcq_history_size),       0x80,    0x80,    0,      0   },
456eef4f27bSRobert Mustacchi         #else
457eef4f27bSRobert Mustacchi         /* Kernel queues are used when RSS or TCP offload is enabled.
458eef4f27bSRobert Mustacchi          * When RSS is enabled, the upper module should modify the
459eef4f27bSRobert Mustacchi          * default settings for these parameters. */
460eef4f27bSRobert Mustacchi         { _OFFSET(kwq_page_cnt),           0,       0,       0,      0 },
461eef4f27bSRobert Mustacchi         { _OFFSET(kcq_page_cnt),           0,       0,       0,      0 },
462eef4f27bSRobert Mustacchi         { _OFFSET(kcq_history_size),       0,       0,       0,      0 },
463eef4f27bSRobert Mustacchi         #endif
464eef4f27bSRobert Mustacchi 
465eef4f27bSRobert Mustacchi         /* Connection kcqe/kwqe history. */
466eef4f27bSRobert Mustacchi         { _OFFSET(con_kcqe_history_size),  0,       0,       0,      0 },
467eef4f27bSRobert Mustacchi         { _OFFSET(con_kwqe_history_size),  0,       0,       0,      0 },
468eef4f27bSRobert Mustacchi         #endif
469eef4f27bSRobert Mustacchi 
470eef4f27bSRobert Mustacchi         { _OFFSET(gen_bd_page_cnt),        2,       2,       1,      127 },
471eef4f27bSRobert Mustacchi         { _OFFSET(max_gen_buf_cnt),        0x8000,  0x8000,  0,      0 },
472eef4f27bSRobert Mustacchi         { _OFFSET(gen_buf_per_alloc),      0x4,    0x4,      0,      0 },
473eef4f27bSRobert Mustacchi 
474eef4f27bSRobert Mustacchi         { _OFFSET(copy_buffered_data),     0,       0,       0,      0 },
475eef4f27bSRobert Mustacchi         { _OFFSET(rcv_buffer_offset),      0x38,    0x38,    0,      0 },
476eef4f27bSRobert Mustacchi         { _OFFSET(enable_syn_rcvq),        0,       0,       0,      0 },
477eef4f27bSRobert Mustacchi 
478eef4f27bSRobert Mustacchi         { _OFFSET(hcopy_desc_cnt),         0,       0,       0,      0 },
479eef4f27bSRobert Mustacchi         { _OFFSET(hcopy_bd_page_cnt),      2,       2,       1,      127 },
480eef4f27bSRobert Mustacchi         { _OFFSET(buffered_kcqe_cnt),      0x80,    0x80,    0,      0 },
481eef4f27bSRobert Mustacchi 
482eef4f27bSRobert Mustacchi         { _OFFSET(deferred_kcqe_cnt),      0x100,   0x100,   0,      0 },
483eef4f27bSRobert Mustacchi 
484eef4f27bSRobert Mustacchi         { _OFFSET(test_mode),              0x60,    0x60,    0,      0 },
485eef4f27bSRobert Mustacchi         { _OFFSET(ofld_cap),               0,       0,       0,      0 },
486eef4f27bSRobert Mustacchi         { _OFFSET(wol_cap),                0,       0,       0,      0 },
487eef4f27bSRobert Mustacchi         { _OFFSET(flow_ctrl_cap),          0,       0,       0,      0 },
488eef4f27bSRobert Mustacchi         { _OFFSET(req_medium),             0,       0,       0,      0xfffff },
489eef4f27bSRobert Mustacchi         { _OFFSET(selective_autoneg),      0,       0,       0,      0 },
490eef4f27bSRobert Mustacchi         { _OFFSET(wire_speed),             1,       0,       0,      0 },
491eef4f27bSRobert Mustacchi         { _OFFSET(phy_addr),               1,       0,       0,      0 },
492eef4f27bSRobert Mustacchi         { _OFFSET(phy_int_mode),           2,       2,       0,      0 },
493eef4f27bSRobert Mustacchi         { _OFFSET(link_chng_mode),         2,       2,       0,      0 },
494eef4f27bSRobert Mustacchi 
495eef4f27bSRobert Mustacchi         { _OFFSET(hc_timer_mode),          0,       0,       0,      0 },
496eef4f27bSRobert Mustacchi         { _OFFSET(ind_comp_limit),         200,     100,     0,      0 },
497eef4f27bSRobert Mustacchi         { _OFFSET(tx_quick_cons_trip_int), 3,       10,      0,      0 },
498eef4f27bSRobert Mustacchi         { _OFFSET(tx_quick_cons_trip),     3,       30,      0,      0 },
499eef4f27bSRobert Mustacchi         { _OFFSET(tx_ticks_int),           30,      10,      0,      0 },
500eef4f27bSRobert Mustacchi         { _OFFSET(tx_ticks),               60,      200,     0,      0 },
501eef4f27bSRobert Mustacchi         { _OFFSET(rx_quick_cons_trip_int), 1,       3,       0,      0 },
502eef4f27bSRobert Mustacchi         { _OFFSET(rx_quick_cons_trip),     2,       1,       0,      0 },
503eef4f27bSRobert Mustacchi         { _OFFSET(rx_ticks_int),           15,      5,       0,      0 },
504eef4f27bSRobert Mustacchi         { _OFFSET(rx_ticks),               45,      1,       0,      0 },
505eef4f27bSRobert Mustacchi         { _OFFSET(comp_prod_trip_int),     2,       3,       0,      0 },
506eef4f27bSRobert Mustacchi         { _OFFSET(comp_prod_trip),         4,       1,       0,      0 },
507eef4f27bSRobert Mustacchi         { _OFFSET(com_ticks_int),          64,      5,       0,      0 },
508eef4f27bSRobert Mustacchi         { _OFFSET(com_ticks),              220,     1,       0,      0 },
509eef4f27bSRobert Mustacchi         { _OFFSET(cmd_ticks_int),          64,      5,       0,      0 },
510eef4f27bSRobert Mustacchi         { _OFFSET(cmd_ticks),              220,     1,       0,      0 },
511eef4f27bSRobert Mustacchi         { _OFFSET(stats_ticks),            1000000, 1000000, 0,      0 },
512eef4f27bSRobert Mustacchi 
513eef4f27bSRobert Mustacchi         /* Xinan per-processor HC configuration. */
514eef4f27bSRobert Mustacchi         { _OFFSET(psb_tx_cons_trip),       0x100010,0x100010,0,      0 },
515eef4f27bSRobert Mustacchi         { _OFFSET(psb_tx_ticks),           0x100040,0x100040,0,      0 },
516eef4f27bSRobert Mustacchi         { _OFFSET(psb_rx_cons_trip),       0x100010,0x100010,0,      0 },
517eef4f27bSRobert Mustacchi         { _OFFSET(psb_rx_ticks),           0x80020, 0x80020, 0,      0 },
518eef4f27bSRobert Mustacchi         { _OFFSET(psb_comp_prod_trip),     0x80008, 0x80008, 0,      0 },
519eef4f27bSRobert Mustacchi         { _OFFSET(psb_com_ticks),          0x400040,0x400040,0,      0 },
520eef4f27bSRobert Mustacchi         { _OFFSET(psb_cmd_ticks),          0x400040,0x400040,0,      0 },
521eef4f27bSRobert Mustacchi         { _OFFSET(psb_period_ticks),       0,       0,       0,      0 },
522eef4f27bSRobert Mustacchi 
523eef4f27bSRobert Mustacchi         { _OFFSET(enable_fir),             1,       1,       0,      0 },
524eef4f27bSRobert Mustacchi         { _OFFSET(num_rchans),             5,       5,       0,      0 },
525eef4f27bSRobert Mustacchi         { _OFFSET(num_wchans),             3,       3,       0,      0 },
526eef4f27bSRobert Mustacchi 
527eef4f27bSRobert Mustacchi         /* One some system, with one_tdma disabled, we will get data
528eef4f27bSRobert Mustacchi          * corruption.  Currently this looks like a chipset bug.  The
529eef4f27bSRobert Mustacchi          * chip group will continue to look into this.  So for now, we
530eef4f27bSRobert Mustacchi          * will enable one_tdma for all chip revisions. */
531eef4f27bSRobert Mustacchi         { _OFFSET(one_tdma),               0,       0,       0,      0 },
532eef4f27bSRobert Mustacchi 
533eef4f27bSRobert Mustacchi         { _OFFSET(ping_pong_dma),          0,       0,       0,      0 },
534eef4f27bSRobert Mustacchi         { _OFFSET(tmr_reload_value1),      0x6c627970, 0,    0,      0 },
535eef4f27bSRobert Mustacchi         { _OFFSET(keep_vlan_tag),          0,       0,       0,      0 },
536eef4f27bSRobert Mustacchi 
537eef4f27bSRobert Mustacchi         { _OFFSET(enable_remote_phy),      0,       0,       0,      0 },
538eef4f27bSRobert Mustacchi         { _OFFSET(rphy_req_medium),        0,       0,       0,      0 },
539eef4f27bSRobert Mustacchi         { _OFFSET(rphy_flow_ctrl_cap),     0,       0,       0,      0 },
540eef4f27bSRobert Mustacchi         { _OFFSET(rphy_selective_autoneg), 0,       0,       0,      0 },
541eef4f27bSRobert Mustacchi         { _OFFSET(rphy_wire_speed),        1,       0,       0,      0 },
542eef4f27bSRobert Mustacchi 
543eef4f27bSRobert Mustacchi         { _OFFSET(bin_mq_mode),            0,       0,       0,      0 },
544eef4f27bSRobert Mustacchi         { _OFFSET(validate_l4_data),       0,       0,       0,      0 },
545eef4f27bSRobert Mustacchi         { _OFFSET(disable_pcie_nfr),       0,       0,       0,      0 },
546eef4f27bSRobert Mustacchi         { _OFFSET(fw_flow_control),        0,       0,       0,      0 },
547eef4f27bSRobert Mustacchi         { _OFFSET(fw_flow_control_wait),   0xffff,  0xffff,  0,      0xffff },
548eef4f27bSRobert Mustacchi         { _OFFSET(ena_large_grc_timeout),  0,       0,       0,      0 },
549eef4f27bSRobert Mustacchi         { _OFFSET(flow_control_reporting_mode),     0,       0,      0,      0 },
550eef4f27bSRobert Mustacchi         { 0,                               0,       0,       0,      0 }
551eef4f27bSRobert Mustacchi     };
552eef4f27bSRobert Mustacchi 
553eef4f27bSRobert Mustacchi     lm_status_t lm_status;
554eef4f27bSRobert Mustacchi     param_entry_t *param;
555eef4f27bSRobert Mustacchi     u32_t val;
556eef4f27bSRobert Mustacchi 
557eef4f27bSRobert Mustacchi     DbgMessage(pdev, INFORMi, "### lm_get_dev_info\n");
558eef4f27bSRobert Mustacchi 
559eef4f27bSRobert Mustacchi     /* Get PCI device and vendor id. */
560eef4f27bSRobert Mustacchi     lm_status = mm_read_pci(
561eef4f27bSRobert Mustacchi         pdev,
562eef4f27bSRobert Mustacchi         OFFSETOF(reg_space_t, pci_config.pcicfg_vendor_id),
563eef4f27bSRobert Mustacchi         &val);
564eef4f27bSRobert Mustacchi     if(lm_status != LM_STATUS_SUCCESS)
565eef4f27bSRobert Mustacchi     {
566eef4f27bSRobert Mustacchi         return lm_status;
567eef4f27bSRobert Mustacchi     }
568eef4f27bSRobert Mustacchi 
569eef4f27bSRobert Mustacchi     pdev->hw_info.vid = (u16_t) val;
570eef4f27bSRobert Mustacchi     DbgMessage1(pdev, INFORMi, "vid 0x%x\n", pdev->hw_info.vid);
571eef4f27bSRobert Mustacchi 
572eef4f27bSRobert Mustacchi     pdev->hw_info.did = (u16_t) (val >> 16);
573eef4f27bSRobert Mustacchi     DbgMessage1(pdev, INFORMi, "did 0x%x\n", pdev->hw_info.did);
574eef4f27bSRobert Mustacchi 
575eef4f27bSRobert Mustacchi     /* Get subsystem and subvendor id. */
576eef4f27bSRobert Mustacchi     lm_status = mm_read_pci(
577eef4f27bSRobert Mustacchi         pdev,
578eef4f27bSRobert Mustacchi         OFFSETOF(reg_space_t, pci_config.pcicfg_subsystem_vendor_id),
579eef4f27bSRobert Mustacchi         &val);
580eef4f27bSRobert Mustacchi     if(lm_status != LM_STATUS_SUCCESS)
581eef4f27bSRobert Mustacchi     {
582eef4f27bSRobert Mustacchi         return lm_status;
583eef4f27bSRobert Mustacchi     }
584eef4f27bSRobert Mustacchi 
585eef4f27bSRobert Mustacchi     pdev->hw_info.svid = (u16_t) val;
586eef4f27bSRobert Mustacchi     DbgMessage1(pdev, INFORMi, "svid 0x%x\n", pdev->hw_info.svid);
587eef4f27bSRobert Mustacchi 
588eef4f27bSRobert Mustacchi     pdev->hw_info.ssid = (u16_t) (val >> 16);
589eef4f27bSRobert Mustacchi     DbgMessage1(pdev, INFORMi, "ssid 0x%x\n", pdev->hw_info.ssid);
590eef4f27bSRobert Mustacchi 
591eef4f27bSRobert Mustacchi     /* Get IRQ, and interrupt pin. */
592eef4f27bSRobert Mustacchi     lm_status = mm_read_pci(
593eef4f27bSRobert Mustacchi         pdev,
594eef4f27bSRobert Mustacchi         OFFSETOF(reg_space_t, pci_config.pcicfg_int_line),
595eef4f27bSRobert Mustacchi         &val);
596eef4f27bSRobert Mustacchi     if(lm_status != LM_STATUS_SUCCESS)
597eef4f27bSRobert Mustacchi     {
598eef4f27bSRobert Mustacchi         return lm_status;
599eef4f27bSRobert Mustacchi     }
600eef4f27bSRobert Mustacchi 
601eef4f27bSRobert Mustacchi     pdev->hw_info.irq = (u8_t) val;
602eef4f27bSRobert Mustacchi     DbgMessage1(pdev, INFORMi, "IRQ 0x%x\n", pdev->hw_info.irq);
603eef4f27bSRobert Mustacchi 
604eef4f27bSRobert Mustacchi     pdev->hw_info.int_pin = (u8_t) (val >> 8);
605eef4f27bSRobert Mustacchi     DbgMessage1(pdev, INFORMi, "Int pin 0x%x\n", pdev->hw_info.int_pin);
606eef4f27bSRobert Mustacchi 
607eef4f27bSRobert Mustacchi     /* Get cache line size. */
608eef4f27bSRobert Mustacchi     lm_status = mm_read_pci(
609eef4f27bSRobert Mustacchi         pdev,
610eef4f27bSRobert Mustacchi         OFFSETOF(reg_space_t, pci_config.pcicfg_cache_line_size),
611eef4f27bSRobert Mustacchi         &val);
612eef4f27bSRobert Mustacchi     if(lm_status != LM_STATUS_SUCCESS)
613eef4f27bSRobert Mustacchi     {
614eef4f27bSRobert Mustacchi         return lm_status;
615eef4f27bSRobert Mustacchi     }
616eef4f27bSRobert Mustacchi 
617eef4f27bSRobert Mustacchi     pdev->hw_info.cache_line_size = (u8_t) val;
618eef4f27bSRobert Mustacchi     DbgMessage1(pdev, INFORMi, "Cache line size 0x%x\n", (u8_t) val);
619eef4f27bSRobert Mustacchi 
620eef4f27bSRobert Mustacchi     pdev->hw_info.latency_timer = (u8_t) (val >> 8);
621eef4f27bSRobert Mustacchi     DbgMessage1(pdev, INFORMi, "Latency timer 0x%x\n", (u8_t) (val >> 8));
622eef4f27bSRobert Mustacchi 
623eef4f27bSRobert Mustacchi     /* Get PCI revision id. */
624eef4f27bSRobert Mustacchi     lm_status = mm_read_pci(
625eef4f27bSRobert Mustacchi         pdev,
626eef4f27bSRobert Mustacchi         OFFSETOF(reg_space_t, pci_config.pcicfg_class_code),
627eef4f27bSRobert Mustacchi         &val);
628eef4f27bSRobert Mustacchi     if(lm_status != LM_STATUS_SUCCESS)
629eef4f27bSRobert Mustacchi     {
630eef4f27bSRobert Mustacchi         return lm_status;
631eef4f27bSRobert Mustacchi     }
632eef4f27bSRobert Mustacchi 
633eef4f27bSRobert Mustacchi     pdev->hw_info.rev_id = (u8_t) val;
634eef4f27bSRobert Mustacchi     DbgMessage1(pdev, INFORMi, "Revision id 0x%x\n", pdev->hw_info.rev_id);
635eef4f27bSRobert Mustacchi 
636eef4f27bSRobert Mustacchi     /* Get the base address. */
637eef4f27bSRobert Mustacchi     lm_status = mm_read_pci(
638eef4f27bSRobert Mustacchi         pdev,
639eef4f27bSRobert Mustacchi         OFFSETOF(reg_space_t, pci_config.pcicfg_bar_1),
640eef4f27bSRobert Mustacchi         &val);
641eef4f27bSRobert Mustacchi     if(lm_status != LM_STATUS_SUCCESS)
642eef4f27bSRobert Mustacchi     {
643eef4f27bSRobert Mustacchi         return lm_status;
644eef4f27bSRobert Mustacchi     }
645eef4f27bSRobert Mustacchi 
646eef4f27bSRobert Mustacchi #ifndef CONFIG_PPC64
647eef4f27bSRobert Mustacchi     pdev->hw_info.mem_base.as_u32.low = val & 0xfffffff0;
648eef4f27bSRobert Mustacchi #endif
649eef4f27bSRobert Mustacchi 
650eef4f27bSRobert Mustacchi     DbgMessage1(pdev, INFORMi, "Mem base low 0x%x\n", pdev->hw_info.mem_base.as_u32.low);
651eef4f27bSRobert Mustacchi 
652eef4f27bSRobert Mustacchi     val = 0;
653eef4f27bSRobert Mustacchi 
654eef4f27bSRobert Mustacchi     lm_status = mm_read_pci(
655eef4f27bSRobert Mustacchi         pdev,
656eef4f27bSRobert Mustacchi         OFFSETOF(reg_space_t, pci_config.pcicfg_bar_2),
657eef4f27bSRobert Mustacchi         &val);
658eef4f27bSRobert Mustacchi     if(lm_status != LM_STATUS_SUCCESS)
659eef4f27bSRobert Mustacchi     {
660eef4f27bSRobert Mustacchi         return lm_status;
661eef4f27bSRobert Mustacchi     }
662eef4f27bSRobert Mustacchi 
663eef4f27bSRobert Mustacchi #ifndef CONFIG_PPC64
664eef4f27bSRobert Mustacchi     pdev->hw_info.mem_base.as_u32.high = val;
665eef4f27bSRobert Mustacchi #endif
666eef4f27bSRobert Mustacchi 
667eef4f27bSRobert Mustacchi     DbgMessage1(pdev, INFORMi, "Mem base high 0x%x\n",
668eef4f27bSRobert Mustacchi         pdev->hw_info.mem_base.as_u32.high);
669eef4f27bSRobert Mustacchi 
670eef4f27bSRobert Mustacchi     /* Enable PCI bus master.  This is supposed to be enabled by the
671eef4f27bSRobert Mustacchi      * BIOS, however, BIOS on older systems may not set this bit. */
672eef4f27bSRobert Mustacchi     lm_status = mm_read_pci(
673eef4f27bSRobert Mustacchi         pdev,
674eef4f27bSRobert Mustacchi         OFFSETOF(reg_space_t, pci_config.pcicfg_command),
675eef4f27bSRobert Mustacchi         &val);
676eef4f27bSRobert Mustacchi     if(lm_status != LM_STATUS_SUCCESS)
677eef4f27bSRobert Mustacchi     {
678eef4f27bSRobert Mustacchi         return lm_status;
679eef4f27bSRobert Mustacchi     }
680eef4f27bSRobert Mustacchi 
681eef4f27bSRobert Mustacchi     /* Error out if memory map is NOT enabled.  This could occur if the
682eef4f27bSRobert Mustacchi      * BIOS is not able to reserve an address range for the device. */
683eef4f27bSRobert Mustacchi     if(!(val & PCICFG_COMMAND_MEM_SPACE))
684eef4f27bSRobert Mustacchi     {
685eef4f27bSRobert Mustacchi         DbgBreakMsg("MEM_SPACE not enabled.\n");
686eef4f27bSRobert Mustacchi 
687eef4f27bSRobert Mustacchi         return LM_STATUS_FAILURE;
688eef4f27bSRobert Mustacchi     }
689eef4f27bSRobert Mustacchi 
690eef4f27bSRobert Mustacchi     val |= PCICFG_COMMAND_BUS_MASTER;
691eef4f27bSRobert Mustacchi 
692eef4f27bSRobert Mustacchi     lm_status = mm_write_pci(
693eef4f27bSRobert Mustacchi         pdev,
694eef4f27bSRobert Mustacchi         OFFSETOF(reg_space_t, pci_config.pcicfg_command),
695eef4f27bSRobert Mustacchi         val);
696eef4f27bSRobert Mustacchi     if(lm_status != LM_STATUS_SUCCESS)
697eef4f27bSRobert Mustacchi     {
698eef4f27bSRobert Mustacchi         return lm_status;
699eef4f27bSRobert Mustacchi     }
700eef4f27bSRobert Mustacchi 
701eef4f27bSRobert Mustacchi     /* Configure byte swap and enable write to the reg_window registers. */
702eef4f27bSRobert Mustacchi     val = PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
703eef4f27bSRobert Mustacchi         PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
704eef4f27bSRobert Mustacchi     lm_status = mm_write_pci(
705eef4f27bSRobert Mustacchi         pdev,
706eef4f27bSRobert Mustacchi         OFFSETOF(reg_space_t, pci_config.pcicfg_misc_config),
707eef4f27bSRobert Mustacchi         val);
708eef4f27bSRobert Mustacchi     if(lm_status != LM_STATUS_SUCCESS)
709eef4f27bSRobert Mustacchi     {
710eef4f27bSRobert Mustacchi         return lm_status;
711eef4f27bSRobert Mustacchi     }
712eef4f27bSRobert Mustacchi 
713eef4f27bSRobert Mustacchi     /* Get the bar size at register 0x408 via PCI configuration indirect. */
714eef4f27bSRobert Mustacchi     lm_status = mm_write_pci(
715eef4f27bSRobert Mustacchi         pdev,
716eef4f27bSRobert Mustacchi         OFFSETOF(pci_config_t, pcicfg_reg_window_address),
717eef4f27bSRobert Mustacchi         OFFSETOF(reg_space_t, pci.pci_config_2));
718eef4f27bSRobert Mustacchi     if(lm_status != LM_STATUS_SUCCESS)
719eef4f27bSRobert Mustacchi     {
720eef4f27bSRobert Mustacchi         return lm_status;
721eef4f27bSRobert Mustacchi     }
722eef4f27bSRobert Mustacchi 
723eef4f27bSRobert Mustacchi     lm_status = mm_read_pci(
724eef4f27bSRobert Mustacchi         pdev,
725eef4f27bSRobert Mustacchi         OFFSETOF(pci_config_t, pcicfg_reg_window),
726eef4f27bSRobert Mustacchi         &val);
727eef4f27bSRobert Mustacchi     if(lm_status != LM_STATUS_SUCCESS)
728eef4f27bSRobert Mustacchi     {
729eef4f27bSRobert Mustacchi         return lm_status;
730eef4f27bSRobert Mustacchi     }
731eef4f27bSRobert Mustacchi 
732eef4f27bSRobert Mustacchi     val &= PCI_CONFIG_2_BAR1_SIZE;
733eef4f27bSRobert Mustacchi     if(val == PCI_CONFIG_2_BAR1_SIZE_DISABLED ||
734eef4f27bSRobert Mustacchi         val > PCI_CONFIG_2_BAR1_SIZE_1G)
735eef4f27bSRobert Mustacchi     {
736eef4f27bSRobert Mustacchi         DbgBreakMsg("Invalid bar size.\n");
737eef4f27bSRobert Mustacchi 
738eef4f27bSRobert Mustacchi         return LM_STATUS_FAILURE;
739eef4f27bSRobert Mustacchi     }
740eef4f27bSRobert Mustacchi 
741eef4f27bSRobert Mustacchi     pdev->hw_info.bar_size = 1 << (val+15);
742eef4f27bSRobert Mustacchi     DbgMessage1(pdev, INFORM, "bar_size 0x%x\n", pdev->hw_info.bar_size);
743eef4f27bSRobert Mustacchi 
744eef4f27bSRobert Mustacchi     /* Map memory base to system address space. */
745eef4f27bSRobert Mustacchi     pdev->vars.regview = (reg_space_t *) mm_map_io_base(
746eef4f27bSRobert Mustacchi         pdev,
747eef4f27bSRobert Mustacchi         pdev->hw_info.mem_base,
748eef4f27bSRobert Mustacchi         pdev->hw_info.bar_size);
749eef4f27bSRobert Mustacchi     if(pdev->vars.regview == NULL)
750eef4f27bSRobert Mustacchi     {
751eef4f27bSRobert Mustacchi         return LM_STATUS_FAILURE;
752eef4f27bSRobert Mustacchi     }
753eef4f27bSRobert Mustacchi     DbgMessage1(pdev, INFORMi, "Mapped base %p\n", pdev->vars.regview);
754eef4f27bSRobert Mustacchi 
755eef4f27bSRobert Mustacchi     #if DBG
756eef4f27bSRobert Mustacchi     /* Make sure byte swapping is properly configured. */
757eef4f27bSRobert Mustacchi     REG_RD(pdev, pci.pci_swap_diag0, &val);
758eef4f27bSRobert Mustacchi 
759eef4f27bSRobert Mustacchi     DbgBreakIf(val != 0x1020304);
760eef4f27bSRobert Mustacchi     #endif
761eef4f27bSRobert Mustacchi 
762eef4f27bSRobert Mustacchi     /* Get the chip revision id and number. */
763eef4f27bSRobert Mustacchi     REG_RD(pdev, misc.misc_id, &pdev->hw_info.chip_id);
764eef4f27bSRobert Mustacchi     DbgMessage1(pdev, INFORMi, "chip id 0x%x\n", pdev->hw_info.chip_id);
765eef4f27bSRobert Mustacchi 
766eef4f27bSRobert Mustacchi     if(CHIP_NUM(pdev) == CHIP_NUM_5709)
767eef4f27bSRobert Mustacchi     {
768eef4f27bSRobert Mustacchi         pdev->hw_info.bus_mode = BUS_MODE_PCIE;
769eef4f27bSRobert Mustacchi     }
770eef4f27bSRobert Mustacchi     else
771eef4f27bSRobert Mustacchi     {
772eef4f27bSRobert Mustacchi         /* Get bus information. */
773eef4f27bSRobert Mustacchi         REG_RD(pdev, pci_config.pcicfg_misc_status, &val);
774eef4f27bSRobert Mustacchi 
775eef4f27bSRobert Mustacchi         if(val & PCICFG_MISC_STATUS_32BIT_DET)
776eef4f27bSRobert Mustacchi         {
777eef4f27bSRobert Mustacchi             pdev->hw_info.bus_width = BUS_WIDTH_32_BIT;
778eef4f27bSRobert Mustacchi             DbgMessage(pdev, INFORM, "32bit bus width.\n");
779eef4f27bSRobert Mustacchi         }
780eef4f27bSRobert Mustacchi         else
781eef4f27bSRobert Mustacchi         {
782eef4f27bSRobert Mustacchi             pdev->hw_info.bus_width = BUS_WIDTH_64_BIT;
783eef4f27bSRobert Mustacchi             DbgMessage(pdev, INFORM, "64bit bus width.\n");
784eef4f27bSRobert Mustacchi         }
785eef4f27bSRobert Mustacchi 
786eef4f27bSRobert Mustacchi         if(val & PCICFG_MISC_STATUS_PCIX_DET)
787eef4f27bSRobert Mustacchi         {
788eef4f27bSRobert Mustacchi             pdev->hw_info.bus_mode = BUS_MODE_PCIX;
789eef4f27bSRobert Mustacchi             DbgMessage(pdev, INFORM, "PCIX bus detected.\n");
790eef4f27bSRobert Mustacchi 
791eef4f27bSRobert Mustacchi             REG_RD(pdev, pci_config.pcicfg_pci_clock_control_bits, &val);
792eef4f27bSRobert Mustacchi             switch(val & PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET)
793eef4f27bSRobert Mustacchi             {
794eef4f27bSRobert Mustacchi             case PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ:
795eef4f27bSRobert Mustacchi                 pdev->hw_info.bus_speed = BUS_SPEED_133_MHZ;
796eef4f27bSRobert Mustacchi                 DbgMessage(pdev, INFORM, "Bus speed is 133Mhz.\n");
797eef4f27bSRobert Mustacchi                 break;
798eef4f27bSRobert Mustacchi 
799eef4f27bSRobert Mustacchi             case PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ:
800eef4f27bSRobert Mustacchi                 pdev->hw_info.bus_speed = BUS_SPEED_100_MHZ;
801eef4f27bSRobert Mustacchi                 DbgMessage(pdev, INFORM, "Bus speed is 100Mhz.\n");
802eef4f27bSRobert Mustacchi                 break;
803eef4f27bSRobert Mustacchi 
804eef4f27bSRobert Mustacchi             case PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ:
805eef4f27bSRobert Mustacchi             case PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ:
806eef4f27bSRobert Mustacchi                 pdev->hw_info.bus_speed = BUS_SPEED_66_MHZ;
807eef4f27bSRobert Mustacchi                 DbgMessage(pdev, INFORM, "Bus speed is 66Mhz.\n");
808eef4f27bSRobert Mustacchi                 break;
809eef4f27bSRobert Mustacchi 
810eef4f27bSRobert Mustacchi             case PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ:
811eef4f27bSRobert Mustacchi             case PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ:
812eef4f27bSRobert Mustacchi                 pdev->hw_info.bus_speed = BUS_SPEED_50_MHZ;
813eef4f27bSRobert Mustacchi                 DbgMessage(pdev, INFORM, "Bus speed is 50Mhz.\n");
814eef4f27bSRobert Mustacchi                 break;
815eef4f27bSRobert Mustacchi 
816eef4f27bSRobert Mustacchi             case PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET:
817eef4f27bSRobert Mustacchi             case PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ:
818eef4f27bSRobert Mustacchi             case PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ:
819eef4f27bSRobert Mustacchi             default:
820eef4f27bSRobert Mustacchi                 pdev->hw_info.bus_speed = BUS_SPEED_33_MHZ;
821eef4f27bSRobert Mustacchi                 DbgMessage(pdev, INFORM, "Bus speed is 33Mhz.\n");
822eef4f27bSRobert Mustacchi                 break;
823eef4f27bSRobert Mustacchi             }
824eef4f27bSRobert Mustacchi         }
825eef4f27bSRobert Mustacchi         else
826eef4f27bSRobert Mustacchi         {
827eef4f27bSRobert Mustacchi             pdev->hw_info.bus_mode = BUS_MODE_PCI;
828eef4f27bSRobert Mustacchi             DbgMessage(pdev, INFORM, "Conventional PCI bus detected.\n");
829eef4f27bSRobert Mustacchi 
830eef4f27bSRobert Mustacchi             if(val & PCICFG_MISC_STATUS_M66EN)
831eef4f27bSRobert Mustacchi             {
832eef4f27bSRobert Mustacchi                 pdev->hw_info.bus_speed = BUS_SPEED_66_MHZ;
833eef4f27bSRobert Mustacchi                 DbgMessage(pdev, INFORM, "Bus speed is 66Mhz.\n");
834eef4f27bSRobert Mustacchi             }
835eef4f27bSRobert Mustacchi             else
836eef4f27bSRobert Mustacchi             {
837eef4f27bSRobert Mustacchi                 pdev->hw_info.bus_speed = BUS_SPEED_33_MHZ;
838eef4f27bSRobert Mustacchi                 DbgMessage(pdev, INFORM, "Bus speed is 33Mhz.\n");
839eef4f27bSRobert Mustacchi             }
840eef4f27bSRobert Mustacchi         }
841eef4f27bSRobert Mustacchi     }
842eef4f27bSRobert Mustacchi 
843eef4f27bSRobert Mustacchi     if(CHIP_ID(pdev) == CHIP_ID_5706_A0 || CHIP_ID(pdev) == CHIP_ID_5706_A1)
844eef4f27bSRobert Mustacchi     {
845eef4f27bSRobert Mustacchi         REG_RD_OFFSET(
846eef4f27bSRobert Mustacchi             pdev,
847eef4f27bSRobert Mustacchi             OFFSETOF(reg_space_t, pci_config.pcicfg_command),
848eef4f27bSRobert Mustacchi             &val);
849eef4f27bSRobert Mustacchi 
850eef4f27bSRobert Mustacchi         /* 5706A0 may falsely detect SERR and PERR. */
851eef4f27bSRobert Mustacchi         if(CHIP_ID(pdev) == CHIP_ID_5706_A0)
852eef4f27bSRobert Mustacchi         {
853eef4f27bSRobert Mustacchi             val &= ~(PCICFG_COMMAND_SERR_ENA | PCICFG_COMMAND_PERR_ENA);
854eef4f27bSRobert Mustacchi         }
855eef4f27bSRobert Mustacchi 
856eef4f27bSRobert Mustacchi         /* 5706A1 PCI 64-bit. */
857eef4f27bSRobert Mustacchi         else if(pdev->hw_info.bus_mode == BUS_MODE_PCI &&
858eef4f27bSRobert Mustacchi             pdev->hw_info.bus_width == BUS_WIDTH_64_BIT)
859eef4f27bSRobert Mustacchi         {
860eef4f27bSRobert Mustacchi             /* E4_5706A1_577: PERR IS INCORRECTLY GENERATED IN PCI 64-BIT.
861eef4f27bSRobert Mustacchi                Description: If the data on the upper AD and CBE busses
862eef4f27bSRobert Mustacchi                   do not match the parity of PAR64 during a 32-bit target
863eef4f27bSRobert Mustacchi                   access, a parity error is incorrectly generated. This
864eef4f27bSRobert Mustacchi                   happens only after a 64-bit master DMA operation has been
865eef4f27bSRobert Mustacchi                   done by the chip.
866eef4f27bSRobert Mustacchi                Scope: All PCI 64-bit systems.
867eef4f27bSRobert Mustacchi                Impact: Ability to indicate a real parity error is lost.
868eef4f27bSRobert Mustacchi                Workaround: Driver needs to clear PERR_EN. */
869eef4f27bSRobert Mustacchi             val &= ~PCICFG_COMMAND_PERR_ENA;
870eef4f27bSRobert Mustacchi         }
871eef4f27bSRobert Mustacchi 
872eef4f27bSRobert Mustacchi         REG_WR_OFFSET(
873eef4f27bSRobert Mustacchi             pdev,
874eef4f27bSRobert Mustacchi             OFFSETOF(reg_space_t, pci_config.pcicfg_command),
875eef4f27bSRobert Mustacchi             val);
876eef4f27bSRobert Mustacchi     }
877eef4f27bSRobert Mustacchi     else if(CHIP_ID(pdev) == CHIP_ID_5708_A0)
878eef4f27bSRobert Mustacchi     {
879eef4f27bSRobert Mustacchi         /* 5708A0 errata. */
880eef4f27bSRobert Mustacchi         REG_RD_OFFSET(
881eef4f27bSRobert Mustacchi             pdev,
882eef4f27bSRobert Mustacchi             OFFSETOF(reg_space_t, pci_config.pcicfg_command),
883eef4f27bSRobert Mustacchi             &val);
884eef4f27bSRobert Mustacchi 
885eef4f27bSRobert Mustacchi         val &= ~(PCICFG_COMMAND_SERR_ENA | PCICFG_COMMAND_PERR_ENA);
886eef4f27bSRobert Mustacchi 
887eef4f27bSRobert Mustacchi         REG_WR_OFFSET(
888eef4f27bSRobert Mustacchi             pdev,
889eef4f27bSRobert Mustacchi             OFFSETOF(reg_space_t, pci_config.pcicfg_command),
890eef4f27bSRobert Mustacchi             val);
891eef4f27bSRobert Mustacchi     }
892eef4f27bSRobert Mustacchi 
893eef4f27bSRobert Mustacchi     /* Get the EPB info. */
894eef4f27bSRobert Mustacchi     if(CHIP_NUM(pdev) == CHIP_NUM_5708)
895eef4f27bSRobert Mustacchi     {
896eef4f27bSRobert Mustacchi         REG_RD_IND(pdev, 0x240000+0x18, &val);
897eef4f27bSRobert Mustacchi         pdev->hw_info.pcie_bus_num = (u8_t) val;
898eef4f27bSRobert Mustacchi 
899eef4f27bSRobert Mustacchi         REG_RD_IND(pdev, 0x240000+0x6c, &val);
900eef4f27bSRobert Mustacchi         pdev->hw_info.pcie_max_width = (u8_t) ((val & 0x3f0) >> 4);
901eef4f27bSRobert Mustacchi 
902eef4f27bSRobert Mustacchi         switch(val & 0xf)
903eef4f27bSRobert Mustacchi         {
904eef4f27bSRobert Mustacchi             case 1:
905eef4f27bSRobert Mustacchi                 pdev->hw_info.pcie_max_speed = PCIE_SPEED_2_5_G;
906eef4f27bSRobert Mustacchi                 break;
907eef4f27bSRobert Mustacchi 
908eef4f27bSRobert Mustacchi             default:
909eef4f27bSRobert Mustacchi                 pdev->hw_info.pcie_max_speed = 0;
910eef4f27bSRobert Mustacchi                 break;
911eef4f27bSRobert Mustacchi         }
912eef4f27bSRobert Mustacchi 
913eef4f27bSRobert Mustacchi         REG_RD_IND(pdev, 0x240000+0x70, &val);
914eef4f27bSRobert Mustacchi         pdev->hw_info.pcie_width = (u8_t) ((val & 0x3f00000) >> 20);
915eef4f27bSRobert Mustacchi 
916eef4f27bSRobert Mustacchi         switch(val & 0xf0000)
917eef4f27bSRobert Mustacchi         {
918eef4f27bSRobert Mustacchi             case 0x10000:
919eef4f27bSRobert Mustacchi                 pdev->hw_info.pcie_speed = PCIE_SPEED_2_5_G;
920eef4f27bSRobert Mustacchi                 break;
921eef4f27bSRobert Mustacchi 
922eef4f27bSRobert Mustacchi             default:
923eef4f27bSRobert Mustacchi                 pdev->hw_info.pcie_speed = 0;
924eef4f27bSRobert Mustacchi                 break;
925eef4f27bSRobert Mustacchi         }
926eef4f27bSRobert Mustacchi     }
927eef4f27bSRobert Mustacchi     else if(CHIP_NUM(pdev) == CHIP_NUM_5709)
928eef4f27bSRobert Mustacchi     {
929eef4f27bSRobert Mustacchi         REG_RD(pdev, pci_config.pcicfg_link_capability, &val);
930eef4f27bSRobert Mustacchi         pdev->hw_info.pcie_max_width =
931eef4f27bSRobert Mustacchi             (u8_t) ((val & PCICFG_LINK_CAPABILITY_MAX_LINK_WIDTH) >> 4);
932eef4f27bSRobert Mustacchi         switch (val & PCICFG_LINK_CAPABILITY_MAX_LINK_SPEED)
933eef4f27bSRobert Mustacchi         {
934eef4f27bSRobert Mustacchi             case PCICFG_LINK_CAPABILITY_MAX_LINK_SPEED_5:
935eef4f27bSRobert Mustacchi                 pdev->hw_info.pcie_max_speed = PCIE_SPEED_5_G;
936eef4f27bSRobert Mustacchi                 break;
937eef4f27bSRobert Mustacchi             case PCICFG_LINK_CAPABILITY_MAX_LINK_SPEED_2_5:
938eef4f27bSRobert Mustacchi                 pdev->hw_info.pcie_max_speed = PCIE_SPEED_2_5_G;
939eef4f27bSRobert Mustacchi                 break;
940eef4f27bSRobert Mustacchi             default:
941eef4f27bSRobert Mustacchi                 pdev->hw_info.pcie_max_speed = 0;
942eef4f27bSRobert Mustacchi                 break;
943eef4f27bSRobert Mustacchi         }
944eef4f27bSRobert Mustacchi 
945eef4f27bSRobert Mustacchi         REG_RD(pdev, pci_config.pcicfg_link_status, &val);
946eef4f27bSRobert Mustacchi         pdev->hw_info.pcie_width =
947eef4f27bSRobert Mustacchi             (u8_t) ((val & PCICFG_LINK_STATUS_NEG_LINK_WIDTH) >> 4);
948eef4f27bSRobert Mustacchi         switch (val & PCICFG_LINK_STATUS_SPEED)
949eef4f27bSRobert Mustacchi         {
950eef4f27bSRobert Mustacchi             case PCICFG_LINK_CAPABILITY_MAX_LINK_SPEED_5:
951eef4f27bSRobert Mustacchi                 pdev->hw_info.pcie_speed = PCIE_SPEED_5_G;
952eef4f27bSRobert Mustacchi                 break;
953eef4f27bSRobert Mustacchi             case PCICFG_LINK_CAPABILITY_MAX_LINK_SPEED_2_5:
954eef4f27bSRobert Mustacchi                 pdev->hw_info.pcie_speed = PCIE_SPEED_2_5_G;
955eef4f27bSRobert Mustacchi                 break;
956eef4f27bSRobert Mustacchi             default:
957eef4f27bSRobert Mustacchi                 pdev->hw_info.pcie_speed = 0;
958eef4f27bSRobert Mustacchi                 break;
959eef4f27bSRobert Mustacchi         }
960eef4f27bSRobert Mustacchi 
961eef4f27bSRobert Mustacchi         REG_RD_IND(pdev, OFFSETOF(reg_space_t, mcp.mcp_toe_id), &val);
962eef4f27bSRobert Mustacchi         if(val & MCP_TOE_ID_FUNCTION_ID)
963eef4f27bSRobert Mustacchi         {
964eef4f27bSRobert Mustacchi             pdev->hw_info.mac_id = 1;
965eef4f27bSRobert Mustacchi         }
966eef4f27bSRobert Mustacchi     }
967eef4f27bSRobert Mustacchi 
968eef4f27bSRobert Mustacchi     /* Get firmware share memory base address. */
969eef4f27bSRobert Mustacchi     REG_RD_IND(
970eef4f27bSRobert Mustacchi         pdev,
971eef4f27bSRobert Mustacchi         MCP_SCRATCHPAD_START + OFFSETOF(shm_hdr_t, shm_hdr_signature),
972eef4f27bSRobert Mustacchi         &val);
973eef4f27bSRobert Mustacchi     if((val & SHM_ADDR_SIGN_MASK) == SHM_ADDR_SIGNATURE)
974eef4f27bSRobert Mustacchi     {
975eef4f27bSRobert Mustacchi         REG_RD_IND(
976eef4f27bSRobert Mustacchi             pdev,
977eef4f27bSRobert Mustacchi             MCP_SCRATCHPAD_START +
978eef4f27bSRobert Mustacchi                 OFFSETOF(shm_hdr_t, shm_addr[pdev->hw_info.mac_id]),
979eef4f27bSRobert Mustacchi             &pdev->hw_info.shmem_base);
980eef4f27bSRobert Mustacchi     }
981eef4f27bSRobert Mustacchi     else
982eef4f27bSRobert Mustacchi     {
983eef4f27bSRobert Mustacchi         /* Pre v1.3.2 bootcode. */
984eef4f27bSRobert Mustacchi         pdev->hw_info.shmem_base = HOST_VIEW_SHMEM_BASE;
985eef4f27bSRobert Mustacchi     }
986eef4f27bSRobert Mustacchi 
987eef4f27bSRobert Mustacchi     /* Get the hw config word. */
988eef4f27bSRobert Mustacchi     REG_RD_IND(
989eef4f27bSRobert Mustacchi         pdev,
990eef4f27bSRobert Mustacchi         pdev->hw_info.shmem_base +
991eef4f27bSRobert Mustacchi             OFFSETOF(shmem_region_t, dev_info.shared_hw_config.config),
992eef4f27bSRobert Mustacchi         &val);
993eef4f27bSRobert Mustacchi     pdev->hw_info.nvm_hw_config = val;
994eef4f27bSRobert Mustacchi 
995eef4f27bSRobert Mustacchi     get_max_conns(
996eef4f27bSRobert Mustacchi         pdev,
997eef4f27bSRobert Mustacchi         &pdev->hw_info.max_toe_conn,
998eef4f27bSRobert Mustacchi         &pdev->hw_info.max_iscsi_conn,
999eef4f27bSRobert Mustacchi         &pdev->hw_info.max_iscsi_pending_tasks);
1000eef4f27bSRobert Mustacchi 
1001eef4f27bSRobert Mustacchi     /* Get the permanent MAC address. */
1002eef4f27bSRobert Mustacchi     REG_RD_IND(
1003eef4f27bSRobert Mustacchi         pdev,
1004eef4f27bSRobert Mustacchi         pdev->hw_info.shmem_base +
1005eef4f27bSRobert Mustacchi             OFFSETOF(shmem_region_t, dev_info.port_hw_config.mac_upper),
1006eef4f27bSRobert Mustacchi         &val);
1007eef4f27bSRobert Mustacchi     pdev->hw_info.mac_addr[0] = (u8_t) (val >> 8);
1008eef4f27bSRobert Mustacchi     pdev->hw_info.mac_addr[1] = (u8_t) val;
1009eef4f27bSRobert Mustacchi 
1010eef4f27bSRobert Mustacchi     REG_RD_IND(
1011eef4f27bSRobert Mustacchi         pdev,
1012eef4f27bSRobert Mustacchi         pdev->hw_info.shmem_base +
1013eef4f27bSRobert Mustacchi             OFFSETOF(shmem_region_t, dev_info.port_hw_config.mac_lower),
1014eef4f27bSRobert Mustacchi         &val);
1015eef4f27bSRobert Mustacchi 
1016eef4f27bSRobert Mustacchi     pdev->hw_info.mac_addr[2] = (u8_t) (val >> 24);
1017eef4f27bSRobert Mustacchi     pdev->hw_info.mac_addr[3] = (u8_t) (val >> 16);
1018eef4f27bSRobert Mustacchi     pdev->hw_info.mac_addr[4] = (u8_t) (val >> 8);
1019eef4f27bSRobert Mustacchi     pdev->hw_info.mac_addr[5] = (u8_t) val;
1020eef4f27bSRobert Mustacchi 
1021eef4f27bSRobert Mustacchi     /* Get iSCSI MAC address. */
1022eef4f27bSRobert Mustacchi     REG_RD_IND(
1023eef4f27bSRobert Mustacchi         pdev,
1024eef4f27bSRobert Mustacchi         pdev->hw_info.shmem_base +
1025eef4f27bSRobert Mustacchi             OFFSETOF(
1026eef4f27bSRobert Mustacchi                 shmem_region_t,
1027eef4f27bSRobert Mustacchi                 dev_info.port_hw_config.iscsi_mac_upper),
1028eef4f27bSRobert Mustacchi          &val);
1029eef4f27bSRobert Mustacchi     pdev->hw_info.iscsi_mac_addr[0] = (u8_t) (val >> 8);
1030eef4f27bSRobert Mustacchi     pdev->hw_info.iscsi_mac_addr[1] = (u8_t) val;
1031eef4f27bSRobert Mustacchi 
1032eef4f27bSRobert Mustacchi     REG_RD_IND(
1033eef4f27bSRobert Mustacchi         pdev,
1034eef4f27bSRobert Mustacchi         pdev->hw_info.shmem_base +
1035eef4f27bSRobert Mustacchi             OFFSETOF(
1036eef4f27bSRobert Mustacchi                 shmem_region_t,
1037eef4f27bSRobert Mustacchi                 dev_info.port_hw_config.iscsi_mac_lower),
1038eef4f27bSRobert Mustacchi         &val);
1039eef4f27bSRobert Mustacchi     pdev->hw_info.iscsi_mac_addr[2] = (u8_t) (val >> 24);
1040eef4f27bSRobert Mustacchi     pdev->hw_info.iscsi_mac_addr[3] = (u8_t) (val >> 16);
1041eef4f27bSRobert Mustacchi     pdev->hw_info.iscsi_mac_addr[4] = (u8_t) (val >> 8);
1042eef4f27bSRobert Mustacchi     pdev->hw_info.iscsi_mac_addr[5] = (u8_t) val;
1043eef4f27bSRobert Mustacchi 
1044eef4f27bSRobert Mustacchi     DbgMessage6(pdev, INFORM, "mac addr: %02x %02x %02x %02x %02x %02x\n",
1045eef4f27bSRobert Mustacchi         pdev->hw_info.mac_addr[0],
1046eef4f27bSRobert Mustacchi         pdev->hw_info.mac_addr[1],
1047eef4f27bSRobert Mustacchi         pdev->hw_info.mac_addr[2],
1048eef4f27bSRobert Mustacchi         pdev->hw_info.mac_addr[3],
1049eef4f27bSRobert Mustacchi         pdev->hw_info.mac_addr[4],
1050eef4f27bSRobert Mustacchi         pdev->hw_info.mac_addr[5]);
1051eef4f27bSRobert Mustacchi 
1052eef4f27bSRobert Mustacchi     DbgBreakIf(LM_DRIVER_MAJOR_VER > 255);
1053eef4f27bSRobert Mustacchi     DbgBreakIf(LM_DRIVER_MINOR_VER > 255);
1054eef4f27bSRobert Mustacchi     DbgBreakIf(LM_DRIVER_REL_NUM > 255);
1055eef4f27bSRobert Mustacchi     DbgBreakIf(LM_DRIVER_FIX_NUM > 255);
1056eef4f27bSRobert Mustacchi 
1057eef4f27bSRobert Mustacchi     pdev->ver_num =
1058eef4f27bSRobert Mustacchi         (LM_DRIVER_MAJOR_VER << 24) |
1059eef4f27bSRobert Mustacchi         (LM_DRIVER_MINOR_VER << 16) |
1060eef4f27bSRobert Mustacchi         (LM_DRIVER_REL_NUM << 8)    |
1061eef4f27bSRobert Mustacchi         LM_DRIVER_FIX_NUM;
1062eef4f27bSRobert Mustacchi 
1063eef4f27bSRobert Mustacchi     (void) build_ver_string(
1064eef4f27bSRobert Mustacchi         (char *)pdev->ver_str,
1065eef4f27bSRobert Mustacchi         sizeof(pdev->ver_str),
1066eef4f27bSRobert Mustacchi         LM_DRIVER_MAJOR_VER,
1067eef4f27bSRobert Mustacchi         LM_DRIVER_MINOR_VER,
1068eef4f27bSRobert Mustacchi         LM_DRIVER_REL_NUM,
1069eef4f27bSRobert Mustacchi         LM_DRIVER_FIX_NUM);
1070eef4f27bSRobert Mustacchi 
1071eef4f27bSRobert Mustacchi     pdev->params.mac_addr[0] = pdev->hw_info.mac_addr[0];
1072eef4f27bSRobert Mustacchi     pdev->params.mac_addr[1] = pdev->hw_info.mac_addr[1];
1073eef4f27bSRobert Mustacchi     pdev->params.mac_addr[2] = pdev->hw_info.mac_addr[2];
1074eef4f27bSRobert Mustacchi     pdev->params.mac_addr[3] = pdev->hw_info.mac_addr[3];
1075eef4f27bSRobert Mustacchi     pdev->params.mac_addr[4] = pdev->hw_info.mac_addr[4];
1076eef4f27bSRobert Mustacchi     pdev->params.mac_addr[5] = pdev->hw_info.mac_addr[5];
1077eef4f27bSRobert Mustacchi 
1078eef4f27bSRobert Mustacchi     /* Initialize the default parameters. */
1079eef4f27bSRobert Mustacchi     param = param_list;
1080eef4f27bSRobert Mustacchi     while(param->offset)
1081eef4f27bSRobert Mustacchi     {
1082eef4f27bSRobert Mustacchi         if(CHIP_REV(pdev) == CHIP_REV_FPGA || CHIP_REV(pdev) == CHIP_REV_IKOS)
1083eef4f27bSRobert Mustacchi         {
1084eef4f27bSRobert Mustacchi             SET_PARAM_VAL(pdev, param, param->fpga_ikos_default);
1085eef4f27bSRobert Mustacchi         }
1086eef4f27bSRobert Mustacchi         else
1087eef4f27bSRobert Mustacchi         {
1088eef4f27bSRobert Mustacchi             SET_PARAM_VAL(pdev, param, param->asic_default);
1089eef4f27bSRobert Mustacchi         }
1090eef4f27bSRobert Mustacchi 
1091eef4f27bSRobert Mustacchi         param++;
1092eef4f27bSRobert Mustacchi     }
1093eef4f27bSRobert Mustacchi 
1094eef4f27bSRobert Mustacchi     if(CHIP_REV(pdev) == CHIP_REV_FPGA || CHIP_REV(pdev) == CHIP_REV_IKOS)
1095eef4f27bSRobert Mustacchi     {
1096eef4f27bSRobert Mustacchi         pdev->params.test_mode |= TEST_MODE_INIT_GEN_BUF_DATA;
1097eef4f27bSRobert Mustacchi         pdev->params.test_mode |= TEST_MODE_SAVE_DUMMY_DMA_DATA;
1098eef4f27bSRobert Mustacchi         pdev->params.test_mode |= TEST_MODE_IGNORE_SHMEM_SIGNATURE;
1099eef4f27bSRobert Mustacchi         pdev->params.test_mode |= TEST_MODE_DRIVER_PULSE_ALWAYS_ALIVE;
1100eef4f27bSRobert Mustacchi     }
1101eef4f27bSRobert Mustacchi 
1102eef4f27bSRobert Mustacchi     /* Some chipsets are not capabable of handling multiple
1103eef4f27bSRobert Mustacchi      * read requests.  Currently we will get data corrupt on
1104eef4f27bSRobert Mustacchi      * Intel 840/860 chipset when one_tdma is not enabled. */
1105eef4f27bSRobert Mustacchi     if(pdev->hw_info.bus_mode == BUS_MODE_PCI)
1106eef4f27bSRobert Mustacchi     {
1107eef4f27bSRobert Mustacchi         if((CHIP_NUM(pdev)==CHIP_NUM_5706 || CHIP_NUM(pdev)==CHIP_NUM_5708) &&
1108eef4f27bSRobert Mustacchi             (CHIP_REV(pdev)==CHIP_REV_FPGA || CHIP_REV(pdev)==CHIP_REV_IKOS))
1109eef4f27bSRobert Mustacchi         {
1110eef4f27bSRobert Mustacchi             pdev->params.ping_pong_dma = FALSE;
1111eef4f27bSRobert Mustacchi         }
1112eef4f27bSRobert Mustacchi         else
1113eef4f27bSRobert Mustacchi         {
1114eef4f27bSRobert Mustacchi             pdev->params.ping_pong_dma = TRUE;
1115eef4f27bSRobert Mustacchi         }
1116eef4f27bSRobert Mustacchi     }
1117eef4f27bSRobert Mustacchi     else
1118eef4f27bSRobert Mustacchi     {
1119eef4f27bSRobert Mustacchi         pdev->params.ping_pong_dma = FALSE;
1120eef4f27bSRobert Mustacchi     }
1121eef4f27bSRobert Mustacchi 
1122eef4f27bSRobert Mustacchi     /* Get the pre-emphasis. */
1123eef4f27bSRobert Mustacchi     REG_RD_IND(
1124eef4f27bSRobert Mustacchi         pdev,
1125eef4f27bSRobert Mustacchi         pdev->hw_info.shmem_base +
1126eef4f27bSRobert Mustacchi             OFFSETOF(shmem_region_t, dev_info.port_hw_config.config),
1127eef4f27bSRobert Mustacchi         &pdev->params.serdes_pre_emphasis);
1128eef4f27bSRobert Mustacchi     pdev->params.serdes_pre_emphasis &= PORT_HW_CFG_SERDES_TXCTL3_MASK;
1129eef4f27bSRobert Mustacchi 
1130eef4f27bSRobert Mustacchi     /* This should be fixed in A1. */
1131eef4f27bSRobert Mustacchi     if(CHIP_ID(pdev) == CHIP_ID_5706_A0)
1132eef4f27bSRobert Mustacchi     {
1133eef4f27bSRobert Mustacchi         if(pdev->hw_info.bus_mode == BUS_MODE_PCIX &&
1134eef4f27bSRobert Mustacchi             pdev->hw_info.bus_speed == BUS_SPEED_133_MHZ)
1135eef4f27bSRobert Mustacchi         {
1136eef4f27bSRobert Mustacchi             pdev->params.num_rchans = 1;
1137eef4f27bSRobert Mustacchi         }
1138eef4f27bSRobert Mustacchi     }
1139eef4f27bSRobert Mustacchi 
1140eef4f27bSRobert Mustacchi     #if defined(DBG) && !defined(EXCLUDE_KQE_SUPPORT)
1141eef4f27bSRobert Mustacchi     pdev->params.con_kcqe_history_size = 256;
1142eef4f27bSRobert Mustacchi     pdev->params.con_kwqe_history_size = 256;
1143eef4f27bSRobert Mustacchi     #endif
1144eef4f27bSRobert Mustacchi 
1145eef4f27bSRobert Mustacchi     if(CHIP_NUM(pdev) == CHIP_NUM_5708 || CHIP_NUM(pdev) == CHIP_NUM_5709)
1146eef4f27bSRobert Mustacchi     {
1147eef4f27bSRobert Mustacchi         if(lm_get_medium(pdev) == LM_MEDIUM_TYPE_FIBER)
1148eef4f27bSRobert Mustacchi         {
1149eef4f27bSRobert Mustacchi             pdev->params.phy_addr = 2;
1150eef4f27bSRobert Mustacchi         }
1151eef4f27bSRobert Mustacchi     }
1152eef4f27bSRobert Mustacchi 
1153eef4f27bSRobert Mustacchi     if(CHIP_NUM(pdev) == CHIP_NUM_5709)
1154eef4f27bSRobert Mustacchi     {
1155eef4f27bSRobert Mustacchi         pdev->params.bin_mq_mode = TRUE;
1156eef4f27bSRobert Mustacchi     }
1157eef4f27bSRobert Mustacchi 
1158eef4f27bSRobert Mustacchi     DbgBreakIf(NUM_RX_CHAIN != NUM_TX_CHAIN);
1159eef4f27bSRobert Mustacchi 
1160eef4f27bSRobert Mustacchi     pdev->rx_info.num_rxq = NUM_RX_CHAIN;
1161eef4f27bSRobert Mustacchi     pdev->tx_info.num_txq = NUM_TX_CHAIN;
1162eef4f27bSRobert Mustacchi     pdev->tx_info.cu_idx = TX_CHAIN_IDX1;
1163eef4f27bSRobert Mustacchi 
1164eef4f27bSRobert Mustacchi     /* see if remote phy is enabled. */
1165eef4f27bSRobert Mustacchi     if(CHIP_REV(pdev) != CHIP_REV_IKOS)
1166eef4f27bSRobert Mustacchi     {
1167eef4f27bSRobert Mustacchi         REG_RD_IND(
1168eef4f27bSRobert Mustacchi             pdev,
1169eef4f27bSRobert Mustacchi             pdev->hw_info.shmem_base +
1170eef4f27bSRobert Mustacchi                 OFFSETOF(shmem_region_t,
1171eef4f27bSRobert Mustacchi                     dev_info.port_feature_config.config),
1172eef4f27bSRobert Mustacchi             &val);
1173eef4f27bSRobert Mustacchi         if(val & PORT_FEATURE_RPHY_ENABLED)
1174eef4f27bSRobert Mustacchi         {
1175eef4f27bSRobert Mustacchi             pdev->params.enable_remote_phy = 1;
1176eef4f27bSRobert Mustacchi         }
1177eef4f27bSRobert Mustacchi     }
1178eef4f27bSRobert Mustacchi 
1179eef4f27bSRobert Mustacchi     if (CHIP_NUM(pdev) == CHIP_NUM_5706 ||
1180eef4f27bSRobert Mustacchi         CHIP_NUM(pdev) == CHIP_NUM_5708)
1181eef4f27bSRobert Mustacchi     {
1182eef4f27bSRobert Mustacchi         // Due to slower speed of RV2P in Teton, we need to limit max
1183eef4f27bSRobert Mustacchi         // number of BD per each end bit. Otherwise, Appscan in RV2P
1184eef4f27bSRobert Mustacchi         // would spend excessive time scanning for end bit.
1185eef4f27bSRobert Mustacchi         pdev->params.limit_l4_rx_bd_cnt = 110;
1186eef4f27bSRobert Mustacchi     }
1187*55fea89dSDan Cross 
1188eef4f27bSRobert Mustacchi     /* Override the defaults with user configurations. */
1189eef4f27bSRobert Mustacchi     lm_status = mm_get_user_config(pdev);
1190eef4f27bSRobert Mustacchi     if(lm_status != LM_STATUS_SUCCESS)
1191eef4f27bSRobert Mustacchi     {
1192eef4f27bSRobert Mustacchi         return lm_status;
1193eef4f27bSRobert Mustacchi     }
1194eef4f27bSRobert Mustacchi 
1195eef4f27bSRobert Mustacchi     /* Make sure share memory is initialized by the firmware.  If not
1196eef4f27bSRobert Mustacchi      * fail initialization.  The check here is a little late as we
1197eef4f27bSRobert Mustacchi      * have already read some share memory info above.  This is ok. */
1198eef4f27bSRobert Mustacchi     REG_RD_IND(
1199eef4f27bSRobert Mustacchi         pdev,
1200eef4f27bSRobert Mustacchi         pdev->hw_info.shmem_base +
1201eef4f27bSRobert Mustacchi             OFFSETOF(shmem_region_t, dev_info.signature),
1202eef4f27bSRobert Mustacchi         &val);
1203eef4f27bSRobert Mustacchi     if((val & DEV_INFO_SIGNATURE_MASK) != DEV_INFO_SIGNATURE)
1204eef4f27bSRobert Mustacchi     {
1205eef4f27bSRobert Mustacchi         if(!(pdev->params.test_mode & TEST_MODE_IGNORE_SHMEM_SIGNATURE))
1206eef4f27bSRobert Mustacchi         {
1207eef4f27bSRobert Mustacchi             DbgBreakMsg("Shmem signature not present.\n");
1208eef4f27bSRobert Mustacchi 
1209eef4f27bSRobert Mustacchi             return LM_STATUS_BAD_SIGNATURE;
1210eef4f27bSRobert Mustacchi         }
1211eef4f27bSRobert Mustacchi 
1212eef4f27bSRobert Mustacchi         pdev->hw_info.mac_addr[0] = 0x00;
1213eef4f27bSRobert Mustacchi         pdev->hw_info.mac_addr[1] = 0x10;
1214eef4f27bSRobert Mustacchi         pdev->hw_info.mac_addr[2] = 0x18;
1215eef4f27bSRobert Mustacchi         pdev->hw_info.mac_addr[3] = 0xff;
1216eef4f27bSRobert Mustacchi         pdev->hw_info.mac_addr[4] = 0xff;
1217eef4f27bSRobert Mustacchi         pdev->hw_info.mac_addr[5] = 0xff;
1218eef4f27bSRobert Mustacchi 
1219eef4f27bSRobert Mustacchi         pdev->hw_info.iscsi_mac_addr[0] = 0x00;
1220eef4f27bSRobert Mustacchi         pdev->hw_info.iscsi_mac_addr[1] = 0x10;
1221eef4f27bSRobert Mustacchi         pdev->hw_info.iscsi_mac_addr[2] = 0x18;
1222eef4f27bSRobert Mustacchi         pdev->hw_info.iscsi_mac_addr[3] = 0xff;
1223eef4f27bSRobert Mustacchi         pdev->hw_info.iscsi_mac_addr[4] = 0xff;
1224eef4f27bSRobert Mustacchi         pdev->hw_info.iscsi_mac_addr[5] = 0xfe;
1225eef4f27bSRobert Mustacchi     }
1226eef4f27bSRobert Mustacchi 
1227eef4f27bSRobert Mustacchi     /* Make sure the parameter values are within range. */
1228eef4f27bSRobert Mustacchi     param = param_list;
1229eef4f27bSRobert Mustacchi     while(param->offset)
1230eef4f27bSRobert Mustacchi     {
1231eef4f27bSRobert Mustacchi         if(param->min != 0 || param->max != 0)
1232eef4f27bSRobert Mustacchi         {
1233eef4f27bSRobert Mustacchi             if(PARAM_VAL(pdev, param) < param->min ||
1234eef4f27bSRobert Mustacchi                 PARAM_VAL(pdev, param) > param->max)
1235eef4f27bSRobert Mustacchi             {
1236eef4f27bSRobert Mustacchi                 if(CHIP_REV(pdev) == CHIP_REV_FPGA ||
1237eef4f27bSRobert Mustacchi                     CHIP_REV(pdev) == CHIP_REV_IKOS)
1238eef4f27bSRobert Mustacchi                 {
1239eef4f27bSRobert Mustacchi                     SET_PARAM_VAL(pdev, param, param->fpga_ikos_default);
1240eef4f27bSRobert Mustacchi                 }
1241eef4f27bSRobert Mustacchi                 else
1242eef4f27bSRobert Mustacchi                 {
1243eef4f27bSRobert Mustacchi                     SET_PARAM_VAL(pdev, param, param->asic_default);
1244eef4f27bSRobert Mustacchi                 }
1245eef4f27bSRobert Mustacchi             }
1246eef4f27bSRobert Mustacchi         }
1247eef4f27bSRobert Mustacchi 
1248eef4f27bSRobert Mustacchi         param++;
1249eef4f27bSRobert Mustacchi     }
1250eef4f27bSRobert Mustacchi 
1251eef4f27bSRobert Mustacchi     /* params.mtu read from the registry does not include the MAC header
1252eef4f27bSRobert Mustacchi      * size.  We need to add the header here. */
1253eef4f27bSRobert Mustacchi     /*
1254eef4f27bSRobert Mustacchi      * get_vbd_params does this aleady
1255eef4f27bSRobert Mustacchi      * pdev->params.mtu += ETHERNET_PACKET_HEADER_SIZE;
1256eef4f27bSRobert Mustacchi      */
1257eef4f27bSRobert Mustacchi 
1258eef4f27bSRobert Mustacchi     #ifndef EXCLUDE_KQE_SUPPORT
1259eef4f27bSRobert Mustacchi     /* The size of the kcq histroy.  This is the number entries that will
1260eef4f27bSRobert Mustacchi      * not be over written by the chip. */
1261eef4f27bSRobert Mustacchi     if(pdev->params.kcq_history_size > (LM_PAGE_SIZE/sizeof(kcqe_t)) *
1262eef4f27bSRobert Mustacchi         pdev->params.kcq_page_cnt - 1)
1263eef4f27bSRobert Mustacchi     {
1264eef4f27bSRobert Mustacchi         pdev->params.kcq_history_size = ((LM_PAGE_SIZE/sizeof(kcqe_t)) *
1265eef4f27bSRobert Mustacchi             pdev->params.kcq_page_cnt) / 2;
1266eef4f27bSRobert Mustacchi     }
1267eef4f27bSRobert Mustacchi     #endif
1268eef4f27bSRobert Mustacchi 
1269eef4f27bSRobert Mustacchi     /* XXX: Exception for Xinan, need a permanent fix. */
1270eef4f27bSRobert Mustacchi     if (CHIP_NUM(pdev) == CHIP_NUM_5709)
1271eef4f27bSRobert Mustacchi     {
1272eef4f27bSRobert Mustacchi         pdev->params.rcv_buffer_offset = 0;
1273eef4f27bSRobert Mustacchi     }
1274eef4f27bSRobert Mustacchi 
1275eef4f27bSRobert Mustacchi     /* Check for a valid mac address. */
1276eef4f27bSRobert Mustacchi     if((pdev->params.mac_addr[0] == 0 &&
1277eef4f27bSRobert Mustacchi         pdev->params.mac_addr[1] == 0 &&
1278eef4f27bSRobert Mustacchi         pdev->params.mac_addr[2] == 0 &&
1279eef4f27bSRobert Mustacchi         pdev->params.mac_addr[3] == 0 &&
1280eef4f27bSRobert Mustacchi         pdev->params.mac_addr[4] == 0 &&
1281eef4f27bSRobert Mustacchi         pdev->params.mac_addr[5] == 0) || (pdev->params.mac_addr[0] & 1))
1282eef4f27bSRobert Mustacchi     {
1283eef4f27bSRobert Mustacchi         DbgMessage(pdev, WARN, "invalid LAA.\n");
1284eef4f27bSRobert Mustacchi 
1285eef4f27bSRobert Mustacchi         pdev->params.mac_addr[0] = pdev->hw_info.mac_addr[0];
1286eef4f27bSRobert Mustacchi         pdev->params.mac_addr[1] = pdev->hw_info.mac_addr[1];
1287eef4f27bSRobert Mustacchi         pdev->params.mac_addr[2] = pdev->hw_info.mac_addr[2];
1288eef4f27bSRobert Mustacchi         pdev->params.mac_addr[3] = pdev->hw_info.mac_addr[3];
1289eef4f27bSRobert Mustacchi         pdev->params.mac_addr[4] = pdev->hw_info.mac_addr[4];
1290eef4f27bSRobert Mustacchi         pdev->params.mac_addr[5] = pdev->hw_info.mac_addr[5];
1291eef4f27bSRobert Mustacchi     }
1292eef4f27bSRobert Mustacchi 
1293eef4f27bSRobert Mustacchi     /* There is a bug in HC that will cause it to stop updating the
1294eef4f27bSRobert Mustacchi      * status block.  This has been shown on some system with L4 traffic
1295eef4f27bSRobert Mustacchi      * goinging.  To workaround this, the trip points and interrupt trip
1296eef4f27bSRobert Mustacchi      * points must be the same and the statistics DMA must be disabled. */
1297eef4f27bSRobert Mustacchi     if(CHIP_ID(pdev) == CHIP_ID_5706_A0)
1298eef4f27bSRobert Mustacchi     {
1299eef4f27bSRobert Mustacchi         pdev->params.tx_quick_cons_trip_int = pdev->params.tx_quick_cons_trip;
1300eef4f27bSRobert Mustacchi         pdev->params.tx_ticks_int = pdev->params.tx_ticks;
1301eef4f27bSRobert Mustacchi         pdev->params.rx_quick_cons_trip_int = pdev->params.rx_quick_cons_trip;
1302eef4f27bSRobert Mustacchi         pdev->params.rx_ticks_int = pdev->params.rx_ticks;
1303eef4f27bSRobert Mustacchi         pdev->params.comp_prod_trip_int = pdev->params.comp_prod_trip;
1304eef4f27bSRobert Mustacchi         pdev->params.com_ticks_int = pdev->params.com_ticks;
1305eef4f27bSRobert Mustacchi         pdev->params.cmd_ticks_int = pdev->params.cmd_ticks;
1306eef4f27bSRobert Mustacchi         pdev->params.stats_ticks = 0;
1307eef4f27bSRobert Mustacchi     }
1308eef4f27bSRobert Mustacchi 
1309eef4f27bSRobert Mustacchi     /* enable_syn_rcvd will direct all tcp segments with syn bit to rxq 1. */
1310eef4f27bSRobert Mustacchi     if(pdev->params.enable_syn_rcvq &&
1311eef4f27bSRobert Mustacchi         NUM_RX_CHAIN > 1 &&
1312eef4f27bSRobert Mustacchi         pdev->params.l2_rx_desc_cnt[1] == 0)
1313eef4f27bSRobert Mustacchi     {
1314eef4f27bSRobert Mustacchi         pdev->params.l2_rx_desc_cnt[1] = 60;
1315eef4f27bSRobert Mustacchi     }
1316eef4f27bSRobert Mustacchi 
1317eef4f27bSRobert Mustacchi     /* Timer mode is broken is 5706_A0 and 5706_A1. */
1318eef4f27bSRobert Mustacchi     if(CHIP_ID(pdev) == CHIP_ID_5706_A0 || CHIP_ID(pdev) == CHIP_ID_5706_A1)
1319eef4f27bSRobert Mustacchi     {
1320eef4f27bSRobert Mustacchi         pdev->params.hc_timer_mode = HC_COLLECT_MODE;
1321eef4f27bSRobert Mustacchi     }
1322eef4f27bSRobert Mustacchi 
1323eef4f27bSRobert Mustacchi     /* Get the current fw_wr_seq. */
1324eef4f27bSRobert Mustacchi     REG_RD_IND(
1325eef4f27bSRobert Mustacchi         pdev,
1326eef4f27bSRobert Mustacchi         pdev->hw_info.shmem_base + OFFSETOF(shmem_region_t, drv_fw_mb.fw_mb),
1327eef4f27bSRobert Mustacchi         &val);
1328eef4f27bSRobert Mustacchi     pdev->vars.fw_wr_seq = val & DRV_MSG_SEQ;
1329eef4f27bSRobert Mustacchi 
1330eef4f27bSRobert Mustacchi     /* see if firmware is remote phy capable. */
1331eef4f27bSRobert Mustacchi     if(pdev->params.enable_remote_phy)
1332eef4f27bSRobert Mustacchi     {
1333eef4f27bSRobert Mustacchi         REG_RD_IND(
1334eef4f27bSRobert Mustacchi             pdev,
1335eef4f27bSRobert Mustacchi             pdev->hw_info.shmem_base +
1336eef4f27bSRobert Mustacchi                 OFFSETOF(shmem_region_t, drv_fw_cap_mb.fw_cap_mb),
1337eef4f27bSRobert Mustacchi             &val);
1338eef4f27bSRobert Mustacchi         if((val & CAPABILITY_SIGNATURE_MASK) != FW_CAP_SIGNATURE ||
1339eef4f27bSRobert Mustacchi             (val & FW_CAP_REMOTE_PHY_CAPABLE) == 0)
1340eef4f27bSRobert Mustacchi         {
1341eef4f27bSRobert Mustacchi             pdev->params.enable_remote_phy = 0;
1342eef4f27bSRobert Mustacchi         }
1343eef4f27bSRobert Mustacchi     }
1344eef4f27bSRobert Mustacchi 
1345eef4f27bSRobert Mustacchi     return LM_STATUS_SUCCESS;
1346eef4f27bSRobert Mustacchi } /* lm_get_dev_info */
1347eef4f27bSRobert Mustacchi 
1348eef4f27bSRobert Mustacchi 
1349eef4f27bSRobert Mustacchi 
1350eef4f27bSRobert Mustacchi #ifndef EXCLUDE_KQE_SUPPORT
1351eef4f27bSRobert Mustacchi /*******************************************************************************
1352eef4f27bSRobert Mustacchi  * Description:
1353eef4f27bSRobert Mustacchi  *
1354eef4f27bSRobert Mustacchi  * Return:
1355eef4f27bSRobert Mustacchi  ******************************************************************************/
1356eef4f27bSRobert Mustacchi STATIC lm_status_t
init_kwq_resc(lm_device_t * pdev)1357eef4f27bSRobert Mustacchi init_kwq_resc(
1358eef4f27bSRobert Mustacchi     lm_device_t *pdev)
1359eef4f27bSRobert Mustacchi {
1360eef4f27bSRobert Mustacchi     u32_t mem_size;
1361eef4f27bSRobert Mustacchi 
1362eef4f27bSRobert Mustacchi     if(pdev->params.kwq_page_cnt == 0)
1363eef4f27bSRobert Mustacchi     {
1364eef4f27bSRobert Mustacchi         return LM_STATUS_SUCCESS;
1365eef4f27bSRobert Mustacchi     }
1366eef4f27bSRobert Mustacchi 
1367eef4f27bSRobert Mustacchi     /* Allocate memory for the page table which does not need to be
1368eef4f27bSRobert Mustacchi      * page aligned.  However the size must be multiple of page size.
1369eef4f27bSRobert Mustacchi      *
1370eef4f27bSRobert Mustacchi      * When initialized, the page table will point to the pages
1371eef4f27bSRobert Mustacchi      * used for the kernel work queue. */
1372eef4f27bSRobert Mustacchi     mem_size = pdev->params.kwq_page_cnt * sizeof(lm_address_t);
1373eef4f27bSRobert Mustacchi     mem_size = (mem_size + LM_PAGE_MASK) & ~LM_PAGE_MASK;
1374eef4f27bSRobert Mustacchi 
1375eef4f27bSRobert Mustacchi     pdev->kq_info.kwq_pgtbl_virt = mm_alloc_phys_mem(
1376eef4f27bSRobert Mustacchi         pdev,
1377eef4f27bSRobert Mustacchi         mem_size,
1378eef4f27bSRobert Mustacchi         &pdev->kq_info.kwq_pgtbl_phy,
1379eef4f27bSRobert Mustacchi         PHYS_MEM_TYPE_NONCACHED,
1380eef4f27bSRobert Mustacchi         NULL);
1381eef4f27bSRobert Mustacchi     if(pdev->kq_info.kwq_pgtbl_virt == NULL)
1382eef4f27bSRobert Mustacchi     {
1383eef4f27bSRobert Mustacchi         return LM_STATUS_RESOURCE;
1384eef4f27bSRobert Mustacchi     }
1385eef4f27bSRobert Mustacchi 
1386eef4f27bSRobert Mustacchi     DbgBreakIf(pdev->kq_info.kwq_pgtbl_phy.as_u32.low & CACHE_LINE_SIZE_MASK);
1387eef4f27bSRobert Mustacchi 
1388eef4f27bSRobert Mustacchi     /* Allocate memory for the kernel work queue.  Here we allocate
1389eef4f27bSRobert Mustacchi      * a physically continuous block of memory and then initialize the
1390eef4f27bSRobert Mustacchi      * page table to pointer to the pages in this block.
1391eef4f27bSRobert Mustacchi      *
1392eef4f27bSRobert Mustacchi      * The kernel work queue is used by the driver similiar to a
1393eef4f27bSRobert Mustacchi      * circular ring.
1394eef4f27bSRobert Mustacchi      *
1395eef4f27bSRobert Mustacchi      * The memory block must be page aligned. */
1396eef4f27bSRobert Mustacchi     mem_size = LM_PAGE_SIZE * pdev->params.kwq_page_cnt;
1397eef4f27bSRobert Mustacchi     pdev->kq_info.kwq_virt = (kwqe_t *) mm_alloc_phys_mem(
1398eef4f27bSRobert Mustacchi         pdev,
1399eef4f27bSRobert Mustacchi         mem_size,
1400eef4f27bSRobert Mustacchi         &pdev->kq_info.kwq_phy,
1401eef4f27bSRobert Mustacchi         PHYS_MEM_TYPE_NONCACHED,
1402eef4f27bSRobert Mustacchi         NULL);
1403eef4f27bSRobert Mustacchi     if(pdev->kq_info.kwq_virt == NULL)
1404eef4f27bSRobert Mustacchi     {
1405eef4f27bSRobert Mustacchi         return LM_STATUS_RESOURCE;
1406eef4f27bSRobert Mustacchi     }
1407eef4f27bSRobert Mustacchi 
1408eef4f27bSRobert Mustacchi     DbgBreakIf(pdev->kq_info.kwq_phy.as_u32.low & CACHE_LINE_SIZE_MASK);
1409eef4f27bSRobert Mustacchi     DbgBreakIf(((u8_t *) pdev->kq_info.kwq_virt - (u8_t *) 0) & LM_PAGE_MASK);
1410eef4f27bSRobert Mustacchi 
1411eef4f27bSRobert Mustacchi     return LM_STATUS_SUCCESS;
1412eef4f27bSRobert Mustacchi } /* init_kwq_resc */
1413eef4f27bSRobert Mustacchi 
1414eef4f27bSRobert Mustacchi 
1415eef4f27bSRobert Mustacchi 
1416eef4f27bSRobert Mustacchi /*******************************************************************************
1417eef4f27bSRobert Mustacchi  * Description:
1418eef4f27bSRobert Mustacchi  *
1419eef4f27bSRobert Mustacchi  * Return:
1420eef4f27bSRobert Mustacchi  ******************************************************************************/
1421eef4f27bSRobert Mustacchi STATIC lm_status_t
init_kcq_resc(lm_device_t * pdev)1422eef4f27bSRobert Mustacchi init_kcq_resc(
1423eef4f27bSRobert Mustacchi     lm_device_t *pdev)
1424eef4f27bSRobert Mustacchi {
1425eef4f27bSRobert Mustacchi 
1426eef4f27bSRobert Mustacchi     u32_t mem_size;
1427eef4f27bSRobert Mustacchi 
1428eef4f27bSRobert Mustacchi     if(pdev->params.kcq_page_cnt == 0)
1429eef4f27bSRobert Mustacchi     {
1430eef4f27bSRobert Mustacchi         return LM_STATUS_SUCCESS;
1431eef4f27bSRobert Mustacchi     }
1432eef4f27bSRobert Mustacchi 
1433eef4f27bSRobert Mustacchi     /* Allocate memory for the page table which does not need to be
1434eef4f27bSRobert Mustacchi      * page aligned.  However the size must be multiple of page size.
1435eef4f27bSRobert Mustacchi      *
1436eef4f27bSRobert Mustacchi      * When initialized, the page table will point to the pages
1437eef4f27bSRobert Mustacchi      * used for the kernel completion queue. */
1438eef4f27bSRobert Mustacchi     mem_size = pdev->params.kcq_page_cnt * sizeof(lm_address_t);
1439eef4f27bSRobert Mustacchi     mem_size = (mem_size + LM_PAGE_MASK) & ~LM_PAGE_MASK;
1440eef4f27bSRobert Mustacchi 
1441eef4f27bSRobert Mustacchi     pdev->kq_info.kcq_pgtbl_virt = mm_alloc_phys_mem(
1442eef4f27bSRobert Mustacchi         pdev,
1443eef4f27bSRobert Mustacchi         mem_size,
1444eef4f27bSRobert Mustacchi         &pdev->kq_info.kcq_pgtbl_phy,
1445eef4f27bSRobert Mustacchi         PHYS_MEM_TYPE_NONCACHED,
1446eef4f27bSRobert Mustacchi         NULL);
1447eef4f27bSRobert Mustacchi     if(pdev->kq_info.kcq_pgtbl_virt == NULL)
1448eef4f27bSRobert Mustacchi     {
1449eef4f27bSRobert Mustacchi         return LM_STATUS_RESOURCE;
1450eef4f27bSRobert Mustacchi     }
1451eef4f27bSRobert Mustacchi 
1452eef4f27bSRobert Mustacchi     DbgBreakIf(pdev->kq_info.kcq_pgtbl_phy.as_u32.low & CACHE_LINE_SIZE_MASK);
1453eef4f27bSRobert Mustacchi 
1454eef4f27bSRobert Mustacchi     /* Allocate memory for the kernel completion queue.  Here we allocate
1455eef4f27bSRobert Mustacchi      * a physically continuous block of memory and then initialize the
1456eef4f27bSRobert Mustacchi      * page table to pointer to the pages in this block.
1457eef4f27bSRobert Mustacchi      *
1458eef4f27bSRobert Mustacchi      * The kernel completion queue is used by the driver similiar to a
1459eef4f27bSRobert Mustacchi      * circular ring.
1460eef4f27bSRobert Mustacchi      *
1461eef4f27bSRobert Mustacchi      * The memory block must be page aligned. */
1462eef4f27bSRobert Mustacchi     mem_size = LM_PAGE_SIZE * pdev->params.kcq_page_cnt;
1463eef4f27bSRobert Mustacchi 
1464eef4f27bSRobert Mustacchi     pdev->kq_info.kcq_virt = (kcqe_t *) mm_alloc_phys_mem(
1465eef4f27bSRobert Mustacchi         pdev,
1466eef4f27bSRobert Mustacchi         mem_size,
1467eef4f27bSRobert Mustacchi         &pdev->kq_info.kcq_phy,
1468eef4f27bSRobert Mustacchi         PHYS_MEM_TYPE_NONCACHED,
1469eef4f27bSRobert Mustacchi         NULL);
1470eef4f27bSRobert Mustacchi     if(pdev->kq_info.kcq_virt == NULL)
1471eef4f27bSRobert Mustacchi     {
1472eef4f27bSRobert Mustacchi         return LM_STATUS_RESOURCE;
1473eef4f27bSRobert Mustacchi     }
1474eef4f27bSRobert Mustacchi 
1475eef4f27bSRobert Mustacchi     DbgBreakIf(pdev->kq_info.kcq_phy.as_u32.low & CACHE_LINE_SIZE_MASK);
1476eef4f27bSRobert Mustacchi     DbgBreakIf(((u8_t *) pdev->kq_info.kcq_virt - (u8_t *) 0) & LM_PAGE_MASK);
1477eef4f27bSRobert Mustacchi 
1478eef4f27bSRobert Mustacchi     return LM_STATUS_SUCCESS;
1479eef4f27bSRobert Mustacchi } /* init_kcq_resc */
1480eef4f27bSRobert Mustacchi #endif /* EXCLUDE_KQE_SUPPORT */
1481eef4f27bSRobert Mustacchi 
1482eef4f27bSRobert Mustacchi 
1483eef4f27bSRobert Mustacchi 
1484eef4f27bSRobert Mustacchi #if INCLUDE_OFLD_SUPPORT
1485eef4f27bSRobert Mustacchi /*******************************************************************************
1486eef4f27bSRobert Mustacchi  * Description:
1487eef4f27bSRobert Mustacchi  *
1488eef4f27bSRobert Mustacchi  * Return:
1489eef4f27bSRobert Mustacchi  ******************************************************************************/
1490eef4f27bSRobert Mustacchi STATIC lm_status_t
init_ofld_resc(lm_device_t * pdev)1491eef4f27bSRobert Mustacchi init_ofld_resc(
1492eef4f27bSRobert Mustacchi     lm_device_t *pdev)
1493eef4f27bSRobert Mustacchi {
1494eef4f27bSRobert Mustacchi     lm_offload_info_t *ofld;
1495eef4f27bSRobert Mustacchi     u32_t mem_size;
1496eef4f27bSRobert Mustacchi     u32_t idx;
1497eef4f27bSRobert Mustacchi 
1498eef4f27bSRobert Mustacchi     ofld = &pdev->ofld;
1499eef4f27bSRobert Mustacchi     ofld->pdev = pdev;
1500eef4f27bSRobert Mustacchi     ofld->pg_cid_hnd_info.max_pending_pg_oflds = 16;
1501eef4f27bSRobert Mustacchi     ofld->pg_cid_hnd_info.pending_pg_ofld_cnt = 0;
1502eef4f27bSRobert Mustacchi 
1503eef4f27bSRobert Mustacchi     s_list_init(&ofld->active_req_list, NULL, NULL, 0);
1504eef4f27bSRobert Mustacchi     s_list_init(&ofld->upload_req_list, NULL, NULL, 0);
1505eef4f27bSRobert Mustacchi 
1506eef4f27bSRobert Mustacchi     for(idx = 0; idx < STATE_BLOCK_CNT; idx++)
1507eef4f27bSRobert Mustacchi     {
1508eef4f27bSRobert Mustacchi         d_list_init(&ofld->state_blks[idx].tcp_list, NULL, NULL, 0);
1509eef4f27bSRobert Mustacchi         d_list_init(&ofld->state_blks[idx].path_list, NULL, NULL, 0);
1510eef4f27bSRobert Mustacchi         d_list_init(&ofld->state_blks[idx].neigh_list, NULL, NULL, 0);
1511eef4f27bSRobert Mustacchi 
1512eef4f27bSRobert Mustacchi         ofld->state_blks[idx].max_conn = 0xffffffff;
1513eef4f27bSRobert Mustacchi 
1514eef4f27bSRobert Mustacchi         ofld->state_blks[idx].state_block_idx = idx;
1515eef4f27bSRobert Mustacchi         ofld->state_blks[idx].ofld = ofld;
1516eef4f27bSRobert Mustacchi 
1517eef4f27bSRobert Mustacchi         ofld->state_blks[idx].params.ticks_per_second = 100;
1518eef4f27bSRobert Mustacchi         ofld->state_blks[idx].params.ack_frequency = 2;
1519eef4f27bSRobert Mustacchi         ofld->state_blks[idx].params.delayed_ack_ticks = 20;
1520*55fea89dSDan Cross         ofld->state_blks[idx].params.max_retx = 10;
1521eef4f27bSRobert Mustacchi         ofld->state_blks[idx].params.doubt_reachability_retx = 8;
1522eef4f27bSRobert Mustacchi         ofld->state_blks[idx].params.sws_prevention_ticks = 10;
1523eef4f27bSRobert Mustacchi         ofld->state_blks[idx].params.dup_ack_threshold = 3;
1524eef4f27bSRobert Mustacchi         ofld->state_blks[idx].params.push_ticks = 20;
1525eef4f27bSRobert Mustacchi         ofld->state_blks[idx].params.nce_stale_ticks = 20;
1526eef4f27bSRobert Mustacchi         ofld->state_blks[idx].params.starting_ip_id = 0x8000;
1527eef4f27bSRobert Mustacchi     }
1528eef4f27bSRobert Mustacchi 
1529eef4f27bSRobert Mustacchi     /* Allocate memory for the generic buffer chain. */
1530eef4f27bSRobert Mustacchi     mem_size = LM_PAGE_SIZE * pdev->params.gen_bd_page_cnt;
1531eef4f27bSRobert Mustacchi     ofld->gen_chain.bd_chain_virt = (rx_bd_t *) mm_alloc_phys_mem(
1532eef4f27bSRobert Mustacchi         pdev,
1533eef4f27bSRobert Mustacchi         mem_size,
1534eef4f27bSRobert Mustacchi         &ofld->gen_chain.bd_chain_phy,
1535eef4f27bSRobert Mustacchi         PHYS_MEM_TYPE_UNSPECIFIED,
1536eef4f27bSRobert Mustacchi         NULL);
1537eef4f27bSRobert Mustacchi     if(ofld->gen_chain.bd_chain_virt == NULL)
1538eef4f27bSRobert Mustacchi     {
1539eef4f27bSRobert Mustacchi         return LM_STATUS_RESOURCE;
1540eef4f27bSRobert Mustacchi     }
1541eef4f27bSRobert Mustacchi 
1542eef4f27bSRobert Mustacchi     DbgBreakIf(ofld->gen_chain.bd_chain_phy.as_u32.low & CACHE_LINE_SIZE_MASK);
1543eef4f27bSRobert Mustacchi 
1544eef4f27bSRobert Mustacchi     ofld->gen_chain.cid_addr = GET_CID_ADDR(GEN_CHAIN_CID);
1545eef4f27bSRobert Mustacchi 
1546eef4f27bSRobert Mustacchi     s_list_init(&ofld->gen_chain.block_list, NULL, NULL, 0);
1547eef4f27bSRobert Mustacchi     s_list_init(&ofld->gen_chain.free_gen_buf_list, NULL, NULL, 0);
1548eef4f27bSRobert Mustacchi     s_list_init(&ofld->gen_chain.active_gen_buf_list, NULL, NULL, 0);
1549eef4f27bSRobert Mustacchi 
1550eef4f27bSRobert Mustacchi     /* Allocate memory for the hcopy chain. */
1551eef4f27bSRobert Mustacchi     if(pdev->params.hcopy_desc_cnt)
1552eef4f27bSRobert Mustacchi     {
1553eef4f27bSRobert Mustacchi         mem_size = LM_PAGE_SIZE * pdev->params.hcopy_bd_page_cnt;
1554eef4f27bSRobert Mustacchi         ofld->hcopy_chain.bd_chain_virt =(tx_bd_t *) mm_alloc_phys_mem(
1555eef4f27bSRobert Mustacchi             pdev,
1556eef4f27bSRobert Mustacchi             mem_size,
1557eef4f27bSRobert Mustacchi             &ofld->hcopy_chain.bd_chain_phy,
1558eef4f27bSRobert Mustacchi             PHYS_MEM_TYPE_UNSPECIFIED,
1559eef4f27bSRobert Mustacchi             NULL);
1560eef4f27bSRobert Mustacchi         if(ofld->hcopy_chain.bd_chain_virt == NULL)
1561eef4f27bSRobert Mustacchi         {
1562eef4f27bSRobert Mustacchi             return LM_STATUS_RESOURCE;
1563eef4f27bSRobert Mustacchi         }
1564eef4f27bSRobert Mustacchi 
1565eef4f27bSRobert Mustacchi         DbgBreakIf(ofld->hcopy_chain.bd_chain_phy.as_u32.low &
1566eef4f27bSRobert Mustacchi             CACHE_LINE_SIZE_MASK);
1567eef4f27bSRobert Mustacchi 
1568eef4f27bSRobert Mustacchi         ofld->hcopy_chain.cid_addr = GET_CID_ADDR(HCOPY_CID);
1569eef4f27bSRobert Mustacchi         ofld->hcopy_chain.hw_con_idx_ptr =
1570eef4f27bSRobert Mustacchi             &pdev->vars.status_virt->deflt.status_rx_quick_consumer_index15;
1571eef4f27bSRobert Mustacchi 
1572eef4f27bSRobert Mustacchi         s_list_init(&ofld->hcopy_chain.pending_descq, NULL, NULL, 0);
1573eef4f27bSRobert Mustacchi         s_list_init(&ofld->hcopy_chain.active_descq, NULL, NULL, 0);
1574eef4f27bSRobert Mustacchi     }
1575eef4f27bSRobert Mustacchi 
1576eef4f27bSRobert Mustacchi     ofld->cid_to_state = (lm_state_header_t **) mm_alloc_mem(
1577eef4f27bSRobert Mustacchi         pdev,
1578eef4f27bSRobert Mustacchi         sizeof(lm_state_header_t *) * MAX_CID,
1579eef4f27bSRobert Mustacchi         NULL);
1580eef4f27bSRobert Mustacchi     if(ofld->cid_to_state == NULL)
1581eef4f27bSRobert Mustacchi     {
1582eef4f27bSRobert Mustacchi         return LM_STATUS_RESOURCE;
1583eef4f27bSRobert Mustacchi     }
1584eef4f27bSRobert Mustacchi 
1585eef4f27bSRobert Mustacchi     return LM_STATUS_SUCCESS;
1586eef4f27bSRobert Mustacchi } /* init_ofld_resc */
1587eef4f27bSRobert Mustacchi #endif /* INCLUDE_OFLD_SUPPORT */
1588eef4f27bSRobert Mustacchi 
1589eef4f27bSRobert Mustacchi 
1590eef4f27bSRobert Mustacchi 
1591eef4f27bSRobert Mustacchi /*******************************************************************************
1592eef4f27bSRobert Mustacchi  * Description:
1593eef4f27bSRobert Mustacchi  *
1594eef4f27bSRobert Mustacchi  * Return:
1595eef4f27bSRobert Mustacchi  ******************************************************************************/
1596eef4f27bSRobert Mustacchi STATIC volatile u16_t *
sblk_tx_con_idx_ptr(lm_device_t * pdev,lm_tx_chain_t * txq)1597eef4f27bSRobert Mustacchi sblk_tx_con_idx_ptr(
1598eef4f27bSRobert Mustacchi     lm_device_t *pdev,
1599eef4f27bSRobert Mustacchi     lm_tx_chain_t *txq)
1600eef4f27bSRobert Mustacchi {
1601eef4f27bSRobert Mustacchi     volatile status_blk_combined_t *sblk;
1602eef4f27bSRobert Mustacchi     volatile u16_t *idx_ptr;
1603eef4f27bSRobert Mustacchi 
1604eef4f27bSRobert Mustacchi     sblk = pdev->vars.status_virt;
1605eef4f27bSRobert Mustacchi 
1606eef4f27bSRobert Mustacchi     if(CHIP_NUM(pdev) == CHIP_NUM_5706 || CHIP_NUM(pdev) == CHIP_NUM_5708)
1607eef4f27bSRobert Mustacchi     {
1608eef4f27bSRobert Mustacchi         switch(txq->idx)
1609eef4f27bSRobert Mustacchi         {
1610eef4f27bSRobert Mustacchi             case TX_CHAIN_IDX0:
1611eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_tx_quick_consumer_index0;
1612eef4f27bSRobert Mustacchi                 break;
1613eef4f27bSRobert Mustacchi 
1614eef4f27bSRobert Mustacchi             case TX_CHAIN_IDX1:
1615eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_tx_quick_consumer_index1;
1616eef4f27bSRobert Mustacchi                 break;
1617eef4f27bSRobert Mustacchi 
1618eef4f27bSRobert Mustacchi             case TX_CHAIN_IDX2:
1619eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_tx_quick_consumer_index2;
1620eef4f27bSRobert Mustacchi                 break;
1621eef4f27bSRobert Mustacchi 
1622eef4f27bSRobert Mustacchi             case TX_CHAIN_IDX3:
1623eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_tx_quick_consumer_index3;
1624eef4f27bSRobert Mustacchi                 break;
1625eef4f27bSRobert Mustacchi 
1626eef4f27bSRobert Mustacchi             default:
1627eef4f27bSRobert Mustacchi                 idx_ptr = NULL;
1628eef4f27bSRobert Mustacchi 
1629eef4f27bSRobert Mustacchi                 DbgBreakIf(txq->idx != pdev->tx_info.cu_idx);
1630eef4f27bSRobert Mustacchi 
1631eef4f27bSRobert Mustacchi                 if(txq->idx == pdev->tx_info.cu_idx)
1632eef4f27bSRobert Mustacchi                 {
1633eef4f27bSRobert Mustacchi                     idx_ptr = &sblk->deflt.status_rx_quick_consumer_index14;
1634eef4f27bSRobert Mustacchi                 }
1635eef4f27bSRobert Mustacchi                 break;
1636eef4f27bSRobert Mustacchi         }
1637eef4f27bSRobert Mustacchi     }
1638eef4f27bSRobert Mustacchi     else
1639eef4f27bSRobert Mustacchi     {
1640eef4f27bSRobert Mustacchi         switch(txq->idx)
1641eef4f27bSRobert Mustacchi         {
1642eef4f27bSRobert Mustacchi             case TX_CHAIN_IDX0:
1643eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_tx_quick_consumer_index0;
1644eef4f27bSRobert Mustacchi                 break;
1645eef4f27bSRobert Mustacchi 
1646eef4f27bSRobert Mustacchi             case TX_CHAIN_IDX1:
1647eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_tx_quick_consumer_index1;
1648eef4f27bSRobert Mustacchi                 break;
1649eef4f27bSRobert Mustacchi 
1650eef4f27bSRobert Mustacchi             case TX_CHAIN_IDX2:
1651eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_tx_quick_consumer_index2;
1652eef4f27bSRobert Mustacchi                 break;
1653eef4f27bSRobert Mustacchi 
1654eef4f27bSRobert Mustacchi             case TX_CHAIN_IDX3:
1655eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_tx_quick_consumer_index3;
1656eef4f27bSRobert Mustacchi                 break;
1657eef4f27bSRobert Mustacchi 
1658eef4f27bSRobert Mustacchi             case TX_CHAIN_IDX4:
1659eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->proc[0].status_pcpu_tx_quick_consumer_index;
1660eef4f27bSRobert Mustacchi                 break;
1661eef4f27bSRobert Mustacchi 
1662eef4f27bSRobert Mustacchi             case TX_CHAIN_IDX5:
1663eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->proc[1].status_pcpu_tx_quick_consumer_index;
1664eef4f27bSRobert Mustacchi                 break;
1665eef4f27bSRobert Mustacchi 
1666eef4f27bSRobert Mustacchi             case TX_CHAIN_IDX6:
1667eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->proc[2].status_pcpu_tx_quick_consumer_index;
1668eef4f27bSRobert Mustacchi                 break;
1669eef4f27bSRobert Mustacchi 
1670eef4f27bSRobert Mustacchi             case TX_CHAIN_IDX7:
1671eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->proc[3].status_pcpu_tx_quick_consumer_index;
1672eef4f27bSRobert Mustacchi                 break;
1673eef4f27bSRobert Mustacchi 
1674eef4f27bSRobert Mustacchi             case TX_CHAIN_IDX8:
1675eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->proc[4].status_pcpu_tx_quick_consumer_index;
1676eef4f27bSRobert Mustacchi                 break;
1677eef4f27bSRobert Mustacchi 
1678eef4f27bSRobert Mustacchi             case TX_CHAIN_IDX9:
1679eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->proc[5].status_pcpu_tx_quick_consumer_index;
1680eef4f27bSRobert Mustacchi                 break;
1681eef4f27bSRobert Mustacchi 
1682eef4f27bSRobert Mustacchi             case TX_CHAIN_IDX10:
1683eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->proc[6].status_pcpu_tx_quick_consumer_index;
1684eef4f27bSRobert Mustacchi                 break;
1685eef4f27bSRobert Mustacchi 
1686eef4f27bSRobert Mustacchi             case TX_CHAIN_IDX11:
1687eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->proc[7].status_pcpu_tx_quick_consumer_index;
1688eef4f27bSRobert Mustacchi                 break;
1689eef4f27bSRobert Mustacchi 
1690eef4f27bSRobert Mustacchi             default:
1691eef4f27bSRobert Mustacchi                 DbgBreakMsg("invalid xinan tx index.\n");
1692eef4f27bSRobert Mustacchi                 idx_ptr = NULL;
1693eef4f27bSRobert Mustacchi                 break;
1694eef4f27bSRobert Mustacchi         }
1695eef4f27bSRobert Mustacchi     }
1696eef4f27bSRobert Mustacchi 
1697eef4f27bSRobert Mustacchi     return idx_ptr;
1698eef4f27bSRobert Mustacchi } /* sblk_tx_con_idx_ptr */
1699eef4f27bSRobert Mustacchi 
1700eef4f27bSRobert Mustacchi 
1701eef4f27bSRobert Mustacchi 
1702eef4f27bSRobert Mustacchi /*******************************************************************************
1703eef4f27bSRobert Mustacchi  * Description:
1704eef4f27bSRobert Mustacchi  *
1705eef4f27bSRobert Mustacchi  * Return:
1706eef4f27bSRobert Mustacchi  ******************************************************************************/
1707eef4f27bSRobert Mustacchi STATIC lm_status_t
init_l2tx_resc(lm_device_t * pdev)1708eef4f27bSRobert Mustacchi init_l2tx_resc(
1709eef4f27bSRobert Mustacchi     lm_device_t *pdev)
1710eef4f27bSRobert Mustacchi {
1711eef4f27bSRobert Mustacchi     lm_tx_chain_t *txq;
1712eef4f27bSRobert Mustacchi     u32_t bd_page_cnt;
1713eef4f27bSRobert Mustacchi     u32_t mem_size;
1714eef4f27bSRobert Mustacchi     u32_t idx;
1715eef4f27bSRobert Mustacchi     u32_t num_tx_chains;
1716eef4f27bSRobert Mustacchi 
1717eef4f27bSRobert Mustacchi #if defined(LM_NON_LEGACY_MODE_SUPPORT)
1718eef4f27bSRobert Mustacchi     num_tx_chains = MAX_TX_CHAIN;
1719eef4f27bSRobert Mustacchi     if(CHIP_NUM(pdev) == CHIP_NUM_5706 || CHIP_NUM(pdev) == CHIP_NUM_5708)
1720eef4f27bSRobert Mustacchi     {
1721eef4f27bSRobert Mustacchi         num_tx_chains = pdev->tx_info.num_txq;
1722eef4f27bSRobert Mustacchi     }
1723eef4f27bSRobert Mustacchi #else
1724eef4f27bSRobert Mustacchi     DbgBreakIf(pdev->tx_info.num_txq > MAX_TX_CHAIN);
1725eef4f27bSRobert Mustacchi     for(idx = pdev->tx_info.num_txq; idx < MAX_TX_CHAIN; idx++)
1726eef4f27bSRobert Mustacchi     {
1727eef4f27bSRobert Mustacchi         pdev->params.l2_tx_bd_page_cnt[idx] = 0;
1728eef4f27bSRobert Mustacchi     }
1729eef4f27bSRobert Mustacchi     num_tx_chains = pdev->tx_info.num_txq;
1730*55fea89dSDan Cross #endif
1731eef4f27bSRobert Mustacchi     for(idx = 0; idx < num_tx_chains; idx++)
1732eef4f27bSRobert Mustacchi     {
1733eef4f27bSRobert Mustacchi         txq = &pdev->tx_info.chain[idx];
1734eef4f27bSRobert Mustacchi         txq->idx = idx;
1735eef4f27bSRobert Mustacchi         txq->cid_addr = GET_CID_ADDR(L2TX_CID_BASE + 2 * txq->idx);
1736eef4f27bSRobert Mustacchi 
1737eef4f27bSRobert Mustacchi         s_list_init(&txq->active_descq, NULL, NULL, 0);
1738eef4f27bSRobert Mustacchi 
1739eef4f27bSRobert Mustacchi         if(CHIP_NUM(pdev) == CHIP_NUM_5706 || CHIP_NUM(pdev) == CHIP_NUM_5708)
1740eef4f27bSRobert Mustacchi         {
1741eef4f27bSRobert Mustacchi             DbgBreakIf(idx > 4);
1742eef4f27bSRobert Mustacchi 
1743eef4f27bSRobert Mustacchi             if(txq->idx == pdev->tx_info.cu_idx && txq->idx != TX_CHAIN_IDX1)
1744eef4f27bSRobert Mustacchi             {
1745eef4f27bSRobert Mustacchi                 DbgBreakIf(idx != 4);
1746eef4f27bSRobert Mustacchi                 txq->cid_addr = GET_CID_ADDR(30);
1747eef4f27bSRobert Mustacchi             }
1748eef4f27bSRobert Mustacchi         }
1749eef4f27bSRobert Mustacchi         else if(txq->idx >= 4)
1750eef4f27bSRobert Mustacchi         {
1751eef4f27bSRobert Mustacchi             DbgBreakIf(idx > 11);
1752eef4f27bSRobert Mustacchi 
1753eef4f27bSRobert Mustacchi             /* Xinan has to use tx1 for catchup because catchup2 uses
1754eef4f27bSRobert Mustacchi              * status_rx_quick_consumer_index14 for completion.  This
1755eef4f27bSRobert Mustacchi              * status block index is not available on Xinan. */
1756eef4f27bSRobert Mustacchi             DbgBreakIf(pdev->tx_info.cu_idx != TX_CHAIN_IDX1);
1757eef4f27bSRobert Mustacchi 
1758eef4f27bSRobert Mustacchi             if(txq->idx >= 4)
1759eef4f27bSRobert Mustacchi             {
1760eef4f27bSRobert Mustacchi                 txq->cid_addr = GET_CID_ADDR(L2TX_TSS_CID_BASE + txq->idx - 4);
1761eef4f27bSRobert Mustacchi             }
1762eef4f27bSRobert Mustacchi         }
1763eef4f27bSRobert Mustacchi 
1764eef4f27bSRobert Mustacchi         bd_page_cnt = pdev->params.l2_tx_bd_page_cnt[txq->idx];
1765eef4f27bSRobert Mustacchi         if(bd_page_cnt)
1766eef4f27bSRobert Mustacchi         {
1767eef4f27bSRobert Mustacchi             mem_size = LM_PAGE_SIZE * bd_page_cnt;
1768eef4f27bSRobert Mustacchi 
1769eef4f27bSRobert Mustacchi             txq->bd_chain_virt = (tx_bd_t *) mm_alloc_phys_mem(
1770eef4f27bSRobert Mustacchi                 pdev,
1771eef4f27bSRobert Mustacchi                 mem_size,
1772eef4f27bSRobert Mustacchi                 &txq->bd_chain_phy,
1773eef4f27bSRobert Mustacchi                 PHYS_MEM_TYPE_NONCACHED,
1774eef4f27bSRobert Mustacchi                 NULL);
1775eef4f27bSRobert Mustacchi             if(txq->bd_chain_virt == NULL)
1776eef4f27bSRobert Mustacchi             {
1777eef4f27bSRobert Mustacchi                 return LM_STATUS_RESOURCE;
1778eef4f27bSRobert Mustacchi             }
1779eef4f27bSRobert Mustacchi 
1780eef4f27bSRobert Mustacchi             DbgBreakIf(txq->bd_chain_phy.as_u32.low & CACHE_LINE_SIZE_MASK);
1781eef4f27bSRobert Mustacchi         }
1782eef4f27bSRobert Mustacchi 
1783eef4f27bSRobert Mustacchi         txq->hw_con_idx_ptr = sblk_tx_con_idx_ptr(pdev, txq);
1784eef4f27bSRobert Mustacchi     }
1785eef4f27bSRobert Mustacchi 
1786eef4f27bSRobert Mustacchi     return LM_STATUS_SUCCESS;
1787eef4f27bSRobert Mustacchi } /* init_l2tx_resc */
1788eef4f27bSRobert Mustacchi 
1789eef4f27bSRobert Mustacchi 
1790eef4f27bSRobert Mustacchi 
1791eef4f27bSRobert Mustacchi /*******************************************************************************
1792eef4f27bSRobert Mustacchi  * Description:
1793eef4f27bSRobert Mustacchi  *
1794eef4f27bSRobert Mustacchi  * Return:
1795eef4f27bSRobert Mustacchi  ******************************************************************************/
1796eef4f27bSRobert Mustacchi STATIC volatile u16_t *
sblk_rx_con_idx_ptr(lm_device_t * pdev,lm_rx_chain_t * rxq)1797eef4f27bSRobert Mustacchi sblk_rx_con_idx_ptr(
1798eef4f27bSRobert Mustacchi     lm_device_t *pdev,
1799eef4f27bSRobert Mustacchi     lm_rx_chain_t *rxq)
1800eef4f27bSRobert Mustacchi {
1801eef4f27bSRobert Mustacchi     volatile status_blk_combined_t *sblk;
1802eef4f27bSRobert Mustacchi     volatile u16_t *idx_ptr;
1803eef4f27bSRobert Mustacchi 
1804eef4f27bSRobert Mustacchi     sblk = pdev->vars.status_virt;
1805eef4f27bSRobert Mustacchi 
1806eef4f27bSRobert Mustacchi     if(CHIP_NUM(pdev) == CHIP_NUM_5706 || CHIP_NUM(pdev) == CHIP_NUM_5708)
1807eef4f27bSRobert Mustacchi     {
1808eef4f27bSRobert Mustacchi         switch(rxq->idx)
1809eef4f27bSRobert Mustacchi         {
1810eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX0:
1811eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index0;
1812eef4f27bSRobert Mustacchi                 break;
1813eef4f27bSRobert Mustacchi 
1814eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX1:
1815eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index1;
1816eef4f27bSRobert Mustacchi                 break;
1817eef4f27bSRobert Mustacchi 
1818eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX2:
1819eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index2;
1820eef4f27bSRobert Mustacchi                 break;
1821eef4f27bSRobert Mustacchi 
1822eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX3:
1823eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index3;
1824eef4f27bSRobert Mustacchi                 break;
1825eef4f27bSRobert Mustacchi 
1826eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX4:
1827eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index4;
1828eef4f27bSRobert Mustacchi                 break;
1829eef4f27bSRobert Mustacchi 
1830eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX5:
1831eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index5;
1832eef4f27bSRobert Mustacchi                 break;
1833eef4f27bSRobert Mustacchi 
1834eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX6:
1835eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index6;
1836eef4f27bSRobert Mustacchi                 break;
1837eef4f27bSRobert Mustacchi 
1838eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX7:
1839eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index7;
1840eef4f27bSRobert Mustacchi                 break;
1841eef4f27bSRobert Mustacchi 
1842eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX8:
1843eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index8;
1844eef4f27bSRobert Mustacchi                 break;
1845eef4f27bSRobert Mustacchi 
1846eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX9:
1847eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index9;
1848eef4f27bSRobert Mustacchi                 break;
1849eef4f27bSRobert Mustacchi 
1850eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX10:
1851eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index10;
1852eef4f27bSRobert Mustacchi                 break;
1853eef4f27bSRobert Mustacchi 
1854eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX11:
1855eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index11;
1856eef4f27bSRobert Mustacchi                 break;
1857eef4f27bSRobert Mustacchi 
1858eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX12:
1859eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index12;
1860eef4f27bSRobert Mustacchi                 break;
1861eef4f27bSRobert Mustacchi 
1862eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX13:
1863eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index13;
1864eef4f27bSRobert Mustacchi                 break;
1865eef4f27bSRobert Mustacchi 
1866eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX14:
1867eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index14;
1868eef4f27bSRobert Mustacchi                 break;
1869eef4f27bSRobert Mustacchi 
1870eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX15:
1871eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index15;
1872eef4f27bSRobert Mustacchi                 break;
1873eef4f27bSRobert Mustacchi 
1874eef4f27bSRobert Mustacchi             default:
1875eef4f27bSRobert Mustacchi                 DbgBreakMsg("invalid teton rx index.\n");
1876eef4f27bSRobert Mustacchi                 idx_ptr = NULL;
1877eef4f27bSRobert Mustacchi                 break;
1878eef4f27bSRobert Mustacchi         }
1879eef4f27bSRobert Mustacchi     }
1880eef4f27bSRobert Mustacchi     else
1881eef4f27bSRobert Mustacchi     {
1882eef4f27bSRobert Mustacchi         switch(rxq->idx)
1883eef4f27bSRobert Mustacchi         {
1884eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX0:
1885eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index0;
1886eef4f27bSRobert Mustacchi                 break;
1887eef4f27bSRobert Mustacchi 
1888eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX1:
1889eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index1;
1890eef4f27bSRobert Mustacchi                 break;
1891eef4f27bSRobert Mustacchi 
1892eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX2:
1893eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index2;
1894eef4f27bSRobert Mustacchi                 break;
1895eef4f27bSRobert Mustacchi 
1896eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX3:
1897eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index3;
1898eef4f27bSRobert Mustacchi                 break;
1899eef4f27bSRobert Mustacchi 
1900eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX4:
1901eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->proc[0].status_pcpu_rx_quick_consumer_index;
1902eef4f27bSRobert Mustacchi                 break;
1903eef4f27bSRobert Mustacchi 
1904eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX5:
1905eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->proc[1].status_pcpu_rx_quick_consumer_index;
1906eef4f27bSRobert Mustacchi                 break;
1907eef4f27bSRobert Mustacchi 
1908eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX6:
1909eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->proc[2].status_pcpu_rx_quick_consumer_index;
1910eef4f27bSRobert Mustacchi                 break;
1911eef4f27bSRobert Mustacchi 
1912eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX7:
1913eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->proc[3].status_pcpu_rx_quick_consumer_index;
1914eef4f27bSRobert Mustacchi                 break;
1915eef4f27bSRobert Mustacchi 
1916eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX8:
1917eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->proc[4].status_pcpu_rx_quick_consumer_index;
1918eef4f27bSRobert Mustacchi                 break;
1919eef4f27bSRobert Mustacchi 
1920eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX9:
1921eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->proc[5].status_pcpu_rx_quick_consumer_index;
1922eef4f27bSRobert Mustacchi                 break;
1923eef4f27bSRobert Mustacchi 
1924eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX10:
1925eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->proc[6].status_pcpu_rx_quick_consumer_index;
1926eef4f27bSRobert Mustacchi                 break;
1927eef4f27bSRobert Mustacchi 
1928eef4f27bSRobert Mustacchi             case RX_CHAIN_IDX11:
1929eef4f27bSRobert Mustacchi                 idx_ptr = &sblk->proc[7].status_pcpu_rx_quick_consumer_index;
1930eef4f27bSRobert Mustacchi                 break;
1931eef4f27bSRobert Mustacchi 
1932eef4f27bSRobert Mustacchi             default:
1933eef4f27bSRobert Mustacchi                 DbgBreakMsg("invalid xinan rx index.\n");
1934eef4f27bSRobert Mustacchi                 idx_ptr = NULL;
1935eef4f27bSRobert Mustacchi                 break;
1936eef4f27bSRobert Mustacchi         }
1937eef4f27bSRobert Mustacchi     }
1938eef4f27bSRobert Mustacchi 
1939eef4f27bSRobert Mustacchi     return idx_ptr;
1940eef4f27bSRobert Mustacchi } /* sblk_rx_con_idx_ptr */
1941eef4f27bSRobert Mustacchi 
1942eef4f27bSRobert Mustacchi 
1943eef4f27bSRobert Mustacchi 
1944eef4f27bSRobert Mustacchi /*******************************************************************************
1945eef4f27bSRobert Mustacchi  * Description:
1946eef4f27bSRobert Mustacchi  *
1947eef4f27bSRobert Mustacchi  * Return:
1948eef4f27bSRobert Mustacchi  ******************************************************************************/
1949eef4f27bSRobert Mustacchi STATIC lm_status_t
alloc_l2rx_desc(lm_device_t * pdev,lm_rx_chain_t * rxq)1950eef4f27bSRobert Mustacchi alloc_l2rx_desc(
1951eef4f27bSRobert Mustacchi     lm_device_t *pdev,
1952eef4f27bSRobert Mustacchi     lm_rx_chain_t *rxq)
1953eef4f27bSRobert Mustacchi {
1954eef4f27bSRobert Mustacchi     u32_t bd_page_cnt;
1955eef4f27bSRobert Mustacchi     lm_packet_t *pkt;
1956eef4f27bSRobert Mustacchi     u32_t desc_size;
1957eef4f27bSRobert Mustacchi     u32_t desc_cnt;
1958eef4f27bSRobert Mustacchi     u8_t *mem_virt;
1959eef4f27bSRobert Mustacchi     u32_t mem_size;
1960eef4f27bSRobert Mustacchi     u32_t idx;
1961eef4f27bSRobert Mustacchi 
1962eef4f27bSRobert Mustacchi     bd_page_cnt = pdev->params.l2_rx_bd_page_cnt[rxq->idx];
1963eef4f27bSRobert Mustacchi     desc_cnt = pdev->params.l2_rx_desc_cnt[rxq->idx];
1964eef4f27bSRobert Mustacchi 
1965eef4f27bSRobert Mustacchi     if(bd_page_cnt == 0 || desc_cnt == 0)
1966eef4f27bSRobert Mustacchi     {
1967eef4f27bSRobert Mustacchi         pdev->params.l2_rx_bd_page_cnt[rxq->idx] = 0;
1968eef4f27bSRobert Mustacchi         pdev->params.l2_rx_desc_cnt[rxq->idx] = 0;
1969eef4f27bSRobert Mustacchi 
1970eef4f27bSRobert Mustacchi         return LM_STATUS_SUCCESS;
1971eef4f27bSRobert Mustacchi     }
1972eef4f27bSRobert Mustacchi 
1973eef4f27bSRobert Mustacchi     mem_size = LM_PAGE_SIZE * bd_page_cnt;
1974eef4f27bSRobert Mustacchi 
1975eef4f27bSRobert Mustacchi     rxq->bd_chain_virt = (rx_bd_t *) mm_alloc_phys_mem(
1976eef4f27bSRobert Mustacchi         pdev,
1977eef4f27bSRobert Mustacchi         mem_size,
1978eef4f27bSRobert Mustacchi         &rxq->bd_chain_phy,
1979eef4f27bSRobert Mustacchi         PHYS_MEM_TYPE_NONCACHED,
1980eef4f27bSRobert Mustacchi         NULL);
1981eef4f27bSRobert Mustacchi     if(rxq->bd_chain_virt == NULL)
1982eef4f27bSRobert Mustacchi     {
1983eef4f27bSRobert Mustacchi         return LM_STATUS_RESOURCE;
1984eef4f27bSRobert Mustacchi     }
1985eef4f27bSRobert Mustacchi 
1986eef4f27bSRobert Mustacchi     DbgBreakIf(rxq->bd_chain_phy.as_u32.low & CACHE_LINE_SIZE_MASK);
1987eef4f27bSRobert Mustacchi 
1988eef4f27bSRobert Mustacchi #ifndef LM_NON_LEGACY_MODE_SUPPORT
1989eef4f27bSRobert Mustacchi     desc_size = mm_desc_size(pdev, DESC_TYPE_L2RX_PACKET) + SIZEOF_SIG;
1990eef4f27bSRobert Mustacchi     mem_size = desc_size * desc_cnt;
1991eef4f27bSRobert Mustacchi 
1992eef4f27bSRobert Mustacchi     mem_virt = (u8_t *) mm_alloc_mem(pdev, mem_size, NULL);
1993eef4f27bSRobert Mustacchi     if(mem_virt == NULL)
1994eef4f27bSRobert Mustacchi     {
1995eef4f27bSRobert Mustacchi         return LM_STATUS_RESOURCE;
1996eef4f27bSRobert Mustacchi     }
1997eef4f27bSRobert Mustacchi 
1998eef4f27bSRobert Mustacchi     for(idx = 0; idx < desc_cnt; idx++)
1999eef4f27bSRobert Mustacchi     {
2000eef4f27bSRobert Mustacchi         pkt = (lm_packet_t *) (mem_virt + SIZEOF_SIG);
2001eef4f27bSRobert Mustacchi         mem_virt += desc_size;
2002eef4f27bSRobert Mustacchi         mem_size -= desc_size;
2003eef4f27bSRobert Mustacchi 
2004eef4f27bSRobert Mustacchi         SIG(pkt) = L2PACKET_RX_SIG;
2005eef4f27bSRobert Mustacchi         // full packet needs to hold mtu + 4-byte CRC32
2006eef4f27bSRobert Mustacchi         pkt->u1.rx.buf_size = pdev->params.mtu + 4;
2007eef4f27bSRobert Mustacchi         pkt->u1.rx.buf_size += L2RX_FRAME_HDR_LEN;
2008eef4f27bSRobert Mustacchi         pkt->u1.rx.buf_size += pdev->params.rcv_buffer_offset;
2009eef4f27bSRobert Mustacchi         pkt->u1.rx.buf_size += CACHE_LINE_SIZE_MASK + 1;
2010eef4f27bSRobert Mustacchi         pkt->u1.rx.buf_size &= ~CACHE_LINE_SIZE_MASK;
2011eef4f27bSRobert Mustacchi 
2012eef4f27bSRobert Mustacchi         s_list_push_tail(&rxq->free_descq, &pkt->link);
2013eef4f27bSRobert Mustacchi     }
2014eef4f27bSRobert Mustacchi 
2015eef4f27bSRobert Mustacchi     DbgBreakIf(mem_size);
2016eef4f27bSRobert Mustacchi     DbgBreakIf(s_list_entry_cnt(&rxq->free_descq) != desc_cnt);
2017eef4f27bSRobert Mustacchi #endif
2018eef4f27bSRobert Mustacchi     return LM_STATUS_SUCCESS;
2019eef4f27bSRobert Mustacchi } /* alloc_l2rx_desc */
2020eef4f27bSRobert Mustacchi 
2021eef4f27bSRobert Mustacchi 
2022eef4f27bSRobert Mustacchi 
2023eef4f27bSRobert Mustacchi /*******************************************************************************
2024eef4f27bSRobert Mustacchi  * Description:
2025eef4f27bSRobert Mustacchi  *
2026eef4f27bSRobert Mustacchi  * Return:
2027eef4f27bSRobert Mustacchi  ******************************************************************************/
2028eef4f27bSRobert Mustacchi STATIC lm_status_t
init_l2rx_resc(lm_device_t * pdev)2029eef4f27bSRobert Mustacchi init_l2rx_resc(
2030eef4f27bSRobert Mustacchi     lm_device_t *pdev)
2031eef4f27bSRobert Mustacchi {
2032eef4f27bSRobert Mustacchi     lm_status_t lm_status;
2033eef4f27bSRobert Mustacchi     lm_rx_chain_t *rxq;
2034eef4f27bSRobert Mustacchi     u32_t idx;
2035eef4f27bSRobert Mustacchi 
2036eef4f27bSRobert Mustacchi #ifndef LM_NON_LEGACY_MODE_SUPPORT
2037eef4f27bSRobert Mustacchi     DbgBreakIf(pdev->rx_info.num_rxq > MAX_RX_CHAIN);
2038eef4f27bSRobert Mustacchi 
2039eef4f27bSRobert Mustacchi     for(idx = pdev->rx_info.num_rxq; idx < MAX_RX_CHAIN; idx++)
2040eef4f27bSRobert Mustacchi     {
2041eef4f27bSRobert Mustacchi         pdev->params.l2_rx_desc_cnt[idx] = 0;
2042eef4f27bSRobert Mustacchi         pdev->params.l2_rx_bd_page_cnt[idx] = 0;
2043eef4f27bSRobert Mustacchi     }
2044*55fea89dSDan Cross #endif
2045eef4f27bSRobert Mustacchi     for(idx = 0; idx < pdev->rx_info.num_rxq ; idx++)
2046eef4f27bSRobert Mustacchi     {
2047eef4f27bSRobert Mustacchi         rxq = &pdev->rx_info.chain[idx];
2048eef4f27bSRobert Mustacchi         rxq->idx = idx;
2049eef4f27bSRobert Mustacchi         rxq->cid_addr = GET_CID_ADDR(L2RX_CID_BASE + rxq->idx);
2050eef4f27bSRobert Mustacchi 
2051eef4f27bSRobert Mustacchi         s_list_init(&rxq->free_descq, NULL, NULL, 0);
2052eef4f27bSRobert Mustacchi         s_list_init(&rxq->active_descq, NULL, NULL, 0);
2053eef4f27bSRobert Mustacchi 
2054eef4f27bSRobert Mustacchi         lm_status = alloc_l2rx_desc(pdev, rxq);
2055eef4f27bSRobert Mustacchi         if(lm_status != LM_STATUS_SUCCESS)
2056eef4f27bSRobert Mustacchi         {
2057eef4f27bSRobert Mustacchi             return lm_status;
2058eef4f27bSRobert Mustacchi         }
2059eef4f27bSRobert Mustacchi 
2060eef4f27bSRobert Mustacchi         rxq->hw_con_idx_ptr = sblk_rx_con_idx_ptr(pdev, rxq);
2061eef4f27bSRobert Mustacchi     }
2062eef4f27bSRobert Mustacchi 
2063eef4f27bSRobert Mustacchi     return LM_STATUS_SUCCESS;
2064eef4f27bSRobert Mustacchi } /* init_l2rx_resc */
2065eef4f27bSRobert Mustacchi 
2066eef4f27bSRobert Mustacchi 
2067eef4f27bSRobert Mustacchi 
2068eef4f27bSRobert Mustacchi /*******************************************************************************
2069eef4f27bSRobert Mustacchi  * Description:
2070eef4f27bSRobert Mustacchi  *
2071eef4f27bSRobert Mustacchi  * Return:
2072eef4f27bSRobert Mustacchi  ******************************************************************************/
2073eef4f27bSRobert Mustacchi STATIC lm_status_t
init_context_resc_5709(lm_device_t * pdev)2074eef4f27bSRobert Mustacchi init_context_resc_5709(
2075eef4f27bSRobert Mustacchi     lm_device_t *pdev)
2076eef4f27bSRobert Mustacchi {
2077eef4f27bSRobert Mustacchi     phy_mem_block_t *ctx_mem;
2078eef4f27bSRobert Mustacchi     u32_t page_align_delta;
2079eef4f27bSRobert Mustacchi     lm_address_t mem_phy;
2080eef4f27bSRobert Mustacchi     u32_t ctx_in_mblk;
2081eef4f27bSRobert Mustacchi     u32_t mem_size;
2082eef4f27bSRobert Mustacchi     u8_t *mem_virt;
2083eef4f27bSRobert Mustacchi     u32_t ctx_cnt;
2084eef4f27bSRobert Mustacchi 
2085eef4f27bSRobert Mustacchi     DbgBreakIf(CHIP_NUM(pdev) != CHIP_NUM_5709);
2086eef4f27bSRobert Mustacchi     DbgBreakIf(CTX_MBLK_SIZE & LM_PAGE_MASK);
2087eef4f27bSRobert Mustacchi     DbgBreakIf(MAX_CTX > 16 * 1024);
2088eef4f27bSRobert Mustacchi     DbgBreakIf(MAX_CTX * ONE_CTX_SIZE / CTX_MBLK_SIZE != NUM_CTX_MBLKS);
2089eef4f27bSRobert Mustacchi     DbgBreakIf((MAX_CTX * ONE_CTX_SIZE) % CTX_MBLK_SIZE);
2090eef4f27bSRobert Mustacchi 
2091eef4f27bSRobert Mustacchi     ctx_mem = &pdev->vars.ctx_mem[0];
2092eef4f27bSRobert Mustacchi     ctx_cnt = 0;
2093eef4f27bSRobert Mustacchi 
2094eef4f27bSRobert Mustacchi     while(ctx_cnt < MAX_CTX)
2095eef4f27bSRobert Mustacchi     {
2096eef4f27bSRobert Mustacchi         ctx_in_mblk = CTX_MBLK_SIZE / ONE_CTX_SIZE;
2097eef4f27bSRobert Mustacchi         if(ctx_cnt + ctx_in_mblk > MAX_CTX)
2098eef4f27bSRobert Mustacchi         {
2099eef4f27bSRobert Mustacchi             ctx_in_mblk = MAX_CTX - ctx_cnt;
2100eef4f27bSRobert Mustacchi         }
2101eef4f27bSRobert Mustacchi 
2102eef4f27bSRobert Mustacchi         mem_size = ctx_in_mblk * ONE_CTX_SIZE;
2103eef4f27bSRobert Mustacchi 
2104eef4f27bSRobert Mustacchi         mem_virt = (u8_t *) mm_alloc_phys_mem(
2105eef4f27bSRobert Mustacchi             pdev,
2106eef4f27bSRobert Mustacchi             mem_size + LM_PAGE_MASK,
2107eef4f27bSRobert Mustacchi             &mem_phy,
2108eef4f27bSRobert Mustacchi             PHYS_MEM_TYPE_NONCACHED,
2109eef4f27bSRobert Mustacchi             NULL);
2110eef4f27bSRobert Mustacchi         if(mem_virt == NULL)
2111eef4f27bSRobert Mustacchi         {
2112eef4f27bSRobert Mustacchi             return LM_STATUS_RESOURCE;
2113eef4f27bSRobert Mustacchi         }
2114eef4f27bSRobert Mustacchi 
2115eef4f27bSRobert Mustacchi         page_align_delta = mem_phy.as_u32.low & LM_PAGE_MASK;
2116eef4f27bSRobert Mustacchi         if(page_align_delta)
2117eef4f27bSRobert Mustacchi         {
2118eef4f27bSRobert Mustacchi             page_align_delta = LM_PAGE_SIZE - page_align_delta;
2119eef4f27bSRobert Mustacchi         }
2120eef4f27bSRobert Mustacchi 
2121eef4f27bSRobert Mustacchi         mem_virt += page_align_delta;
2122eef4f27bSRobert Mustacchi         LM_INC64(&mem_phy, page_align_delta);
2123eef4f27bSRobert Mustacchi 
2124eef4f27bSRobert Mustacchi         ctx_mem->start_phy = mem_phy;
2125eef4f27bSRobert Mustacchi         ctx_mem->start = mem_virt;
2126eef4f27bSRobert Mustacchi         ctx_mem->size = mem_size;
2127eef4f27bSRobert Mustacchi         ctx_mem++;
2128eef4f27bSRobert Mustacchi 
2129eef4f27bSRobert Mustacchi         ctx_cnt += mem_size / ONE_CTX_SIZE;
2130eef4f27bSRobert Mustacchi     }
2131eef4f27bSRobert Mustacchi 
2132eef4f27bSRobert Mustacchi     return LM_STATUS_SUCCESS;
2133eef4f27bSRobert Mustacchi } /* init_context_resc_5709 */
2134eef4f27bSRobert Mustacchi 
2135eef4f27bSRobert Mustacchi 
2136eef4f27bSRobert Mustacchi 
2137eef4f27bSRobert Mustacchi /*******************************************************************************
2138eef4f27bSRobert Mustacchi  * Description:
2139eef4f27bSRobert Mustacchi  *
2140eef4f27bSRobert Mustacchi  * Return:
2141eef4f27bSRobert Mustacchi  ******************************************************************************/
2142eef4f27bSRobert Mustacchi lm_status_t
lm_init_resc(lm_device_t * pdev)2143eef4f27bSRobert Mustacchi lm_init_resc(
2144eef4f27bSRobert Mustacchi     lm_device_t *pdev)
2145eef4f27bSRobert Mustacchi {
2146eef4f27bSRobert Mustacchi     lm_status_t lm_status;
2147eef4f27bSRobert Mustacchi     lm_address_t mem_phy;
2148eef4f27bSRobert Mustacchi     u8_t *mem_virt;
2149eef4f27bSRobert Mustacchi     u32_t mem_size;
2150eef4f27bSRobert Mustacchi 
2151eef4f27bSRobert Mustacchi     #ifndef EXCLUDE_KQE_SUPPORT
2152eef4f27bSRobert Mustacchi     lm_status = init_kwq_resc(pdev);
2153eef4f27bSRobert Mustacchi     if(lm_status != LM_STATUS_SUCCESS)
2154eef4f27bSRobert Mustacchi     {
2155eef4f27bSRobert Mustacchi         return lm_status;
2156eef4f27bSRobert Mustacchi     }
2157eef4f27bSRobert Mustacchi 
2158eef4f27bSRobert Mustacchi     lm_status = init_kcq_resc(pdev);
2159eef4f27bSRobert Mustacchi     if(lm_status != LM_STATUS_SUCCESS)
2160eef4f27bSRobert Mustacchi     {
2161eef4f27bSRobert Mustacchi         return lm_status;
2162eef4f27bSRobert Mustacchi     }
2163eef4f27bSRobert Mustacchi     #endif
2164eef4f27bSRobert Mustacchi 
2165eef4f27bSRobert Mustacchi     #if INCLUDE_OFLD_SUPPORT
2166eef4f27bSRobert Mustacchi     lm_status = init_ofld_resc(pdev);
2167eef4f27bSRobert Mustacchi     if(lm_status != LM_STATUS_SUCCESS)
2168eef4f27bSRobert Mustacchi     {
2169eef4f27bSRobert Mustacchi         return lm_status;
2170eef4f27bSRobert Mustacchi     }
2171eef4f27bSRobert Mustacchi     #endif
2172eef4f27bSRobert Mustacchi 
2173eef4f27bSRobert Mustacchi     DbgBreakIf(sizeof(status_blk_combined_t) > STATUS_BLOCK_BUFFER_SIZE);
2174eef4f27bSRobert Mustacchi     DbgBreakIf(sizeof(statistics_block_t) > CHIP_STATS_BUFFER_SIZE);
2175eef4f27bSRobert Mustacchi 
2176eef4f27bSRobert Mustacchi     mem_size = STATUS_BLOCK_BUFFER_SIZE +
2177eef4f27bSRobert Mustacchi     #ifndef EXCLUDE_RSS_SUPPORT
2178eef4f27bSRobert Mustacchi         RSS_INDIRECTION_TABLE_SIZE +
2179eef4f27bSRobert Mustacchi         RSS_LOOKUP_TABLE_WA +
2180eef4f27bSRobert Mustacchi     #endif
2181eef4f27bSRobert Mustacchi         CHIP_STATS_BUFFER_SIZE;
2182eef4f27bSRobert Mustacchi 
2183eef4f27bSRobert Mustacchi     mem_virt = mm_alloc_phys_mem(
2184eef4f27bSRobert Mustacchi         pdev,
2185eef4f27bSRobert Mustacchi         mem_size,
2186eef4f27bSRobert Mustacchi         &mem_phy,
2187eef4f27bSRobert Mustacchi         PHYS_MEM_TYPE_NONCACHED,
2188eef4f27bSRobert Mustacchi         NULL);
2189eef4f27bSRobert Mustacchi     if(mem_virt == NULL)
2190eef4f27bSRobert Mustacchi     {
2191eef4f27bSRobert Mustacchi         return LM_STATUS_RESOURCE;
2192eef4f27bSRobert Mustacchi     }
2193eef4f27bSRobert Mustacchi 
2194eef4f27bSRobert Mustacchi     DbgBreakIf(mem_phy.as_u32.low & CACHE_LINE_SIZE_MASK);
2195eef4f27bSRobert Mustacchi 
2196eef4f27bSRobert Mustacchi     pdev->vars.status_virt = (status_blk_combined_t *) mem_virt;
2197eef4f27bSRobert Mustacchi     pdev->vars.status_phy = mem_phy;
2198eef4f27bSRobert Mustacchi     mem_virt += STATUS_BLOCK_BUFFER_SIZE;
2199eef4f27bSRobert Mustacchi     LM_INC64(&mem_phy, STATUS_BLOCK_BUFFER_SIZE);
2200eef4f27bSRobert Mustacchi 
2201eef4f27bSRobert Mustacchi     pdev->vars.stats_virt = (statistics_block_t *) mem_virt;
2202eef4f27bSRobert Mustacchi     pdev->vars.stats_phy = mem_phy;
2203eef4f27bSRobert Mustacchi     mem_virt += CHIP_STATS_BUFFER_SIZE;
2204eef4f27bSRobert Mustacchi     LM_INC64(&mem_phy, CHIP_STATS_BUFFER_SIZE);
2205eef4f27bSRobert Mustacchi 
2206eef4f27bSRobert Mustacchi     #ifndef EXCLUDE_RSS_SUPPORT
2207eef4f27bSRobert Mustacchi     pdev->rx_info.rss_ind_table_virt = mem_virt;
2208eef4f27bSRobert Mustacchi     pdev->rx_info.rss_ind_table_phy = mem_phy;
2209eef4f27bSRobert Mustacchi     #endif
2210eef4f27bSRobert Mustacchi 
2211eef4f27bSRobert Mustacchi     if(CHIP_NUM(pdev) == CHIP_NUM_5709)
2212eef4f27bSRobert Mustacchi     {
2213eef4f27bSRobert Mustacchi         lm_status = init_context_resc_5709(pdev);
2214eef4f27bSRobert Mustacchi         if(lm_status != LM_STATUS_SUCCESS)
2215eef4f27bSRobert Mustacchi         {
2216eef4f27bSRobert Mustacchi             return lm_status;
2217eef4f27bSRobert Mustacchi         }
2218eef4f27bSRobert Mustacchi     }
2219eef4f27bSRobert Mustacchi 
2220eef4f27bSRobert Mustacchi     lm_status = init_l2tx_resc(pdev);
2221eef4f27bSRobert Mustacchi     if(lm_status != LM_STATUS_SUCCESS)
2222eef4f27bSRobert Mustacchi     {
2223eef4f27bSRobert Mustacchi         return lm_status;
2224eef4f27bSRobert Mustacchi     }
2225eef4f27bSRobert Mustacchi 
2226eef4f27bSRobert Mustacchi     lm_status = init_l2rx_resc(pdev);
2227eef4f27bSRobert Mustacchi     if(lm_status != LM_STATUS_SUCCESS)
2228eef4f27bSRobert Mustacchi     {
2229eef4f27bSRobert Mustacchi         return lm_status;
2230eef4f27bSRobert Mustacchi     }
2231eef4f27bSRobert Mustacchi 
2232eef4f27bSRobert Mustacchi     lm_clear_nwuf(pdev);
2233eef4f27bSRobert Mustacchi 
2234eef4f27bSRobert Mustacchi     return LM_STATUS_SUCCESS;
2235eef4f27bSRobert Mustacchi } /* lm_init_resc */
2236eef4f27bSRobert Mustacchi 
2237eef4f27bSRobert Mustacchi 
2238eef4f27bSRobert Mustacchi 
2239eef4f27bSRobert Mustacchi /*******************************************************************************
2240eef4f27bSRobert Mustacchi  * Description:
2241eef4f27bSRobert Mustacchi  *
2242eef4f27bSRobert Mustacchi  * Return:
2243eef4f27bSRobert Mustacchi  ******************************************************************************/
2244eef4f27bSRobert Mustacchi STATIC u32_t
compute_crc32(u8_t * buf,u32_t buf_size)2245eef4f27bSRobert Mustacchi compute_crc32(
2246eef4f27bSRobert Mustacchi     u8_t *buf,
2247eef4f27bSRobert Mustacchi     u32_t buf_size)
2248eef4f27bSRobert Mustacchi {
2249eef4f27bSRobert Mustacchi     u32_t reg;
2250eef4f27bSRobert Mustacchi     u32_t tmp;
2251eef4f27bSRobert Mustacchi     u32_t j;
2252eef4f27bSRobert Mustacchi     u32_t k;
2253eef4f27bSRobert Mustacchi 
2254eef4f27bSRobert Mustacchi     reg = 0xffffffff;
2255eef4f27bSRobert Mustacchi 
2256eef4f27bSRobert Mustacchi     for(j = 0; j < buf_size; j++)
2257eef4f27bSRobert Mustacchi     {
2258eef4f27bSRobert Mustacchi         reg ^= buf[j];
2259eef4f27bSRobert Mustacchi 
2260eef4f27bSRobert Mustacchi         for(k = 0; k < 8; k++)
2261eef4f27bSRobert Mustacchi         {
2262eef4f27bSRobert Mustacchi             tmp = reg & 0x01;
2263eef4f27bSRobert Mustacchi 
2264eef4f27bSRobert Mustacchi             reg >>= 1;
2265eef4f27bSRobert Mustacchi 
2266eef4f27bSRobert Mustacchi             if(tmp)
2267eef4f27bSRobert Mustacchi             {
2268eef4f27bSRobert Mustacchi                 reg ^= 0xedb88320;
2269eef4f27bSRobert Mustacchi             }
2270eef4f27bSRobert Mustacchi         }
2271eef4f27bSRobert Mustacchi     }
2272eef4f27bSRobert Mustacchi 
2273eef4f27bSRobert Mustacchi     return ~reg;
2274eef4f27bSRobert Mustacchi } /* compute_crc32 */
2275eef4f27bSRobert Mustacchi 
2276eef4f27bSRobert Mustacchi 
2277eef4f27bSRobert Mustacchi 
2278eef4f27bSRobert Mustacchi #define NUM_MC_HASH_REGISTERS                   8
2279eef4f27bSRobert Mustacchi /*******************************************************************************
2280eef4f27bSRobert Mustacchi  * Description:
2281eef4f27bSRobert Mustacchi  *
2282eef4f27bSRobert Mustacchi  * Return:
2283eef4f27bSRobert Mustacchi  ******************************************************************************/
2284eef4f27bSRobert Mustacchi STATIC void
set_mc_hash_reg(lm_device_t * pdev,lm_mc_table_t * mc_table)2285eef4f27bSRobert Mustacchi set_mc_hash_reg(
2286eef4f27bSRobert Mustacchi     lm_device_t *pdev,
2287eef4f27bSRobert Mustacchi     lm_mc_table_t *mc_table)
2288eef4f27bSRobert Mustacchi {
2289eef4f27bSRobert Mustacchi     u32_t hash_reg[NUM_MC_HASH_REGISTERS];
2290eef4f27bSRobert Mustacchi     u32_t reg_idx;
2291eef4f27bSRobert Mustacchi     u32_t bit_pos;
2292eef4f27bSRobert Mustacchi     u32_t idx;
2293eef4f27bSRobert Mustacchi     u32_t crc32;
2294eef4f27bSRobert Mustacchi 
2295eef4f27bSRobert Mustacchi     /* Program the MC hash registers.
2296eef4f27bSRobert Mustacchi      *    The MAC hash registers are used to help discard unwanted
2297eef4f27bSRobert Mustacchi      *    multicast packets as they are received from the external
2298eef4f27bSRobert Mustacchi      *    media.  The destination address is fed into the normal CRC
2299eef4f27bSRobert Mustacchi      *    algorithm in order to generate a hash function.  The most
2300eef4f27bSRobert Mustacchi      *    significant bits of the CRC are then used without any inversion
2301eef4f27bSRobert Mustacchi      *    in reverse order to index into a hash table which is comprised
2302eef4f27bSRobert Mustacchi      *    of these MAC hash registers.  If the CRC is calculated by
2303eef4f27bSRobert Mustacchi      *    shifting right then the rightmost bits of the CRC can be
2304eef4f27bSRobert Mustacchi      *    directly used with no additional inversion or bit swapping
2305eef4f27bSRobert Mustacchi      *    required.  All four MAC hash registers are used such that
2306eef4f27bSRobert Mustacchi      *    register 1 bit-32 is the most significant hash table entry
2307eef4f27bSRobert Mustacchi      *    and register 8 bit-0 is the least significant hash table entry.
2308eef4f27bSRobert Mustacchi      *    This follows the normal big-endian ordering used throughout
2309eef4f27bSRobert Mustacchi      *    Teton.  Since there are 256 hash table entries, 8-bits are
2310eef4f27bSRobert Mustacchi      *    used from the CRC.  The hash registers are ignored if the
2311eef4f27bSRobert Mustacchi      *    receive MAC is in promiscuous mode. */
2312eef4f27bSRobert Mustacchi     for(idx = 0; idx < NUM_MC_HASH_REGISTERS; idx++)
2313eef4f27bSRobert Mustacchi     {
2314eef4f27bSRobert Mustacchi         hash_reg[idx] = 0;
2315eef4f27bSRobert Mustacchi     }
2316eef4f27bSRobert Mustacchi 
2317eef4f27bSRobert Mustacchi     for(idx = 0; idx < mc_table->entry_cnt; idx++)
2318eef4f27bSRobert Mustacchi     {
2319eef4f27bSRobert Mustacchi         crc32 = compute_crc32(
2320eef4f27bSRobert Mustacchi             mc_table->addr_arr[idx].mc_addr,
2321eef4f27bSRobert Mustacchi             ETHERNET_ADDRESS_SIZE);
2322eef4f27bSRobert Mustacchi 
2323eef4f27bSRobert Mustacchi         /* The most significant 7 bits of the CRC32 (no inversion),
2324eef4f27bSRobert Mustacchi          * are used to index into one of the possible 128 bit positions. */
2325eef4f27bSRobert Mustacchi         bit_pos = ~crc32 & 0xff;
2326eef4f27bSRobert Mustacchi 
2327eef4f27bSRobert Mustacchi         reg_idx = (bit_pos & 0xe0) >> 5;
2328eef4f27bSRobert Mustacchi 
2329eef4f27bSRobert Mustacchi         bit_pos &= 0x1f;
2330eef4f27bSRobert Mustacchi 
2331eef4f27bSRobert Mustacchi         hash_reg[reg_idx] |= (1 << bit_pos);
2332eef4f27bSRobert Mustacchi     }
2333eef4f27bSRobert Mustacchi 
2334eef4f27bSRobert Mustacchi     for(idx = 0; idx < NUM_MC_HASH_REGISTERS; idx++)
2335eef4f27bSRobert Mustacchi     {
2336eef4f27bSRobert Mustacchi         REG_WR(pdev, emac.emac_multicast_hash[idx], hash_reg[idx]);
2337eef4f27bSRobert Mustacchi     }
2338eef4f27bSRobert Mustacchi } /* set_mc_hash_reg */
2339eef4f27bSRobert Mustacchi 
2340eef4f27bSRobert Mustacchi 
2341eef4f27bSRobert Mustacchi 
2342eef4f27bSRobert Mustacchi /*******************************************************************************
2343eef4f27bSRobert Mustacchi  * Description:
2344eef4f27bSRobert Mustacchi  *
2345eef4f27bSRobert Mustacchi  * Return:
2346eef4f27bSRobert Mustacchi  ******************************************************************************/
2347eef4f27bSRobert Mustacchi lm_status_t
lm_set_rx_mask(lm_device_t * pdev,u32_t user_idx,lm_rx_mask_t rx_mask)2348eef4f27bSRobert Mustacchi lm_set_rx_mask(
2349eef4f27bSRobert Mustacchi     lm_device_t *pdev,
2350eef4f27bSRobert Mustacchi     u32_t user_idx,
2351eef4f27bSRobert Mustacchi     lm_rx_mask_t rx_mask)
2352eef4f27bSRobert Mustacchi {
2353eef4f27bSRobert Mustacchi     u32_t combined_rx_mask;
2354eef4f27bSRobert Mustacchi     u32_t invalid_rx_mask;
2355eef4f27bSRobert Mustacchi     u32_t sort_mode;
2356eef4f27bSRobert Mustacchi     u32_t rx_mode;
2357eef4f27bSRobert Mustacchi     u32_t val;
2358eef4f27bSRobert Mustacchi     u32_t idx;
2359eef4f27bSRobert Mustacchi 
2360eef4f27bSRobert Mustacchi     if(user_idx >= MAX_RX_FILTER_USER_CNT)
2361eef4f27bSRobert Mustacchi     {
2362eef4f27bSRobert Mustacchi         DbgBreakMsg("invalid user index.\n");
2363eef4f27bSRobert Mustacchi 
2364eef4f27bSRobert Mustacchi         return LM_STATUS_FAILURE;
2365eef4f27bSRobert Mustacchi     }
2366eef4f27bSRobert Mustacchi 
2367eef4f27bSRobert Mustacchi     combined_rx_mask = rx_mask;
2368eef4f27bSRobert Mustacchi     for(idx = 0; idx < MAX_RX_FILTER_USER_CNT; idx++)
2369eef4f27bSRobert Mustacchi     {
2370eef4f27bSRobert Mustacchi         if(idx != user_idx)
2371eef4f27bSRobert Mustacchi         {
2372eef4f27bSRobert Mustacchi             combined_rx_mask |= pdev->rx_info.mask[idx];
2373eef4f27bSRobert Mustacchi         }
2374eef4f27bSRobert Mustacchi     }
2375eef4f27bSRobert Mustacchi 
2376eef4f27bSRobert Mustacchi     /* Set up the rx_mode register. */
2377eef4f27bSRobert Mustacchi     invalid_rx_mask = combined_rx_mask;
2378eef4f27bSRobert Mustacchi     REG_RD(pdev, emac.emac_rx_mode, &rx_mode);
2379eef4f27bSRobert Mustacchi 
2380eef4f27bSRobert Mustacchi     if(invalid_rx_mask & LM_RX_MASK_ACCEPT_UNICAST)
2381eef4f27bSRobert Mustacchi     {
2382eef4f27bSRobert Mustacchi         invalid_rx_mask &= ~LM_RX_MASK_ACCEPT_UNICAST;
2383eef4f27bSRobert Mustacchi     }
2384eef4f27bSRobert Mustacchi 
2385eef4f27bSRobert Mustacchi     if(invalid_rx_mask & LM_RX_MASK_ACCEPT_MULTICAST)
2386eef4f27bSRobert Mustacchi     {
2387eef4f27bSRobert Mustacchi         invalid_rx_mask &= ~LM_RX_MASK_ACCEPT_MULTICAST;
2388eef4f27bSRobert Mustacchi     }
2389eef4f27bSRobert Mustacchi 
2390eef4f27bSRobert Mustacchi     if(invalid_rx_mask & LM_RX_MASK_ACCEPT_ALL_MULTICAST)
2391eef4f27bSRobert Mustacchi     {
2392eef4f27bSRobert Mustacchi         invalid_rx_mask &= ~LM_RX_MASK_ACCEPT_ALL_MULTICAST;
2393eef4f27bSRobert Mustacchi     }
2394eef4f27bSRobert Mustacchi 
2395eef4f27bSRobert Mustacchi     rx_mode &= ~EMAC_RX_MODE_FILT_BROADCAST;
2396eef4f27bSRobert Mustacchi     if(invalid_rx_mask & LM_RX_MASK_ACCEPT_BROADCAST)
2397eef4f27bSRobert Mustacchi     {
2398eef4f27bSRobert Mustacchi         invalid_rx_mask &= ~LM_RX_MASK_ACCEPT_BROADCAST;
2399eef4f27bSRobert Mustacchi     }
2400eef4f27bSRobert Mustacchi     else
2401eef4f27bSRobert Mustacchi     {
2402eef4f27bSRobert Mustacchi         rx_mode |= EMAC_RX_MODE_FILT_BROADCAST;
2403eef4f27bSRobert Mustacchi     }
2404eef4f27bSRobert Mustacchi 
2405eef4f27bSRobert Mustacchi     rx_mode &= ~(EMAC_RX_MODE_ACCEPT_RUNTS | EMAC_RX_MODE_ACCEPT_OVERSIZE);
2406eef4f27bSRobert Mustacchi     if(invalid_rx_mask & LM_RX_MASK_ACCEPT_ERROR_PACKET)
2407eef4f27bSRobert Mustacchi     {
2408eef4f27bSRobert Mustacchi         invalid_rx_mask &= ~LM_RX_MASK_ACCEPT_ERROR_PACKET;
2409eef4f27bSRobert Mustacchi         rx_mode |= EMAC_RX_MODE_ACCEPT_RUNTS |
2410eef4f27bSRobert Mustacchi             EMAC_RX_MODE_ACCEPT_OVERSIZE |
2411eef4f27bSRobert Mustacchi             EMAC_RX_MODE_NO_CRC_CHK;
2412eef4f27bSRobert Mustacchi     }
2413eef4f27bSRobert Mustacchi 
2414eef4f27bSRobert Mustacchi     rx_mode &= ~EMAC_RX_MODE_PROMISCUOUS;
2415eef4f27bSRobert Mustacchi     if(invalid_rx_mask & LM_RX_MASK_PROMISCUOUS_MODE)
2416eef4f27bSRobert Mustacchi     {
2417eef4f27bSRobert Mustacchi         invalid_rx_mask &= ~LM_RX_MASK_PROMISCUOUS_MODE;
2418eef4f27bSRobert Mustacchi         rx_mode |= EMAC_RX_MODE_PROMISCUOUS;
2419eef4f27bSRobert Mustacchi     }
2420eef4f27bSRobert Mustacchi 
2421eef4f27bSRobert Mustacchi     if(invalid_rx_mask)
2422eef4f27bSRobert Mustacchi     {
2423eef4f27bSRobert Mustacchi         DbgBreakMsg("Unknown rx_mask.\n");
2424eef4f27bSRobert Mustacchi 
2425eef4f27bSRobert Mustacchi         return LM_STATUS_FAILURE;
2426eef4f27bSRobert Mustacchi     }
2427eef4f27bSRobert Mustacchi 
2428eef4f27bSRobert Mustacchi     if(combined_rx_mask & LM_RX_MASK_ACCEPT_ALL_MULTICAST)
2429eef4f27bSRobert Mustacchi     {
2430eef4f27bSRobert Mustacchi         for(idx = 0; idx < NUM_MC_HASH_REGISTERS; idx++)
2431eef4f27bSRobert Mustacchi         {
2432eef4f27bSRobert Mustacchi             REG_WR(pdev, emac.emac_multicast_hash[idx], 0xffffffff);
2433eef4f27bSRobert Mustacchi         }
2434eef4f27bSRobert Mustacchi     }
2435eef4f27bSRobert Mustacchi     else if(combined_rx_mask & LM_RX_MASK_ACCEPT_MULTICAST)
2436eef4f27bSRobert Mustacchi     {
2437eef4f27bSRobert Mustacchi         set_mc_hash_reg(pdev, &pdev->mc_table);
2438eef4f27bSRobert Mustacchi     }
2439eef4f27bSRobert Mustacchi     else
2440eef4f27bSRobert Mustacchi     {
2441eef4f27bSRobert Mustacchi         for(idx = 0; idx < NUM_MC_HASH_REGISTERS; idx++)
2442eef4f27bSRobert Mustacchi         {
2443eef4f27bSRobert Mustacchi             REG_WR(pdev, emac.emac_multicast_hash[idx], 0);
2444eef4f27bSRobert Mustacchi         }
2445eef4f27bSRobert Mustacchi     }
2446eef4f27bSRobert Mustacchi 
2447eef4f27bSRobert Mustacchi     pdev->rx_info.mask[user_idx] = rx_mask;
2448eef4f27bSRobert Mustacchi 
2449eef4f27bSRobert Mustacchi     val = rx_mode | EMAC_RX_MODE_SORT_MODE;
2450eef4f27bSRobert Mustacchi     if(pdev->params.keep_vlan_tag)
2451eef4f27bSRobert Mustacchi     {
2452eef4f27bSRobert Mustacchi         val |= EMAC_RX_MODE_KEEP_VLAN_TAG;
2453eef4f27bSRobert Mustacchi     }
2454eef4f27bSRobert Mustacchi     REG_WR(pdev, emac.emac_rx_mode, val);
2455eef4f27bSRobert Mustacchi 
2456eef4f27bSRobert Mustacchi     /* Set up the sort_mode register. */
2457eef4f27bSRobert Mustacchi     sort_mode = 0;
2458eef4f27bSRobert Mustacchi 
2459eef4f27bSRobert Mustacchi     if(rx_mask & LM_RX_MASK_ACCEPT_UNICAST)
2460eef4f27bSRobert Mustacchi     {
2461eef4f27bSRobert Mustacchi         sort_mode |= 1 << user_idx;
2462eef4f27bSRobert Mustacchi     }
2463eef4f27bSRobert Mustacchi 
2464eef4f27bSRobert Mustacchi     if(rx_mask & LM_RX_MASK_ACCEPT_MULTICAST)
2465eef4f27bSRobert Mustacchi     {
2466eef4f27bSRobert Mustacchi         sort_mode |= RPM_SORT_USER0_MC_HSH_EN;
2467eef4f27bSRobert Mustacchi     }
2468eef4f27bSRobert Mustacchi 
2469eef4f27bSRobert Mustacchi     if(rx_mask & LM_RX_MASK_ACCEPT_ALL_MULTICAST)
2470eef4f27bSRobert Mustacchi     {
2471eef4f27bSRobert Mustacchi         sort_mode |= RPM_SORT_USER0_MC_EN;
2472eef4f27bSRobert Mustacchi     }
2473eef4f27bSRobert Mustacchi 
2474eef4f27bSRobert Mustacchi     if(rx_mask & LM_RX_MASK_ACCEPT_BROADCAST)
2475eef4f27bSRobert Mustacchi     {
2476eef4f27bSRobert Mustacchi         sort_mode |= RPM_SORT_USER0_BC_EN;
2477eef4f27bSRobert Mustacchi     }
2478eef4f27bSRobert Mustacchi 
2479eef4f27bSRobert Mustacchi     if(rx_mask & LM_RX_MASK_PROMISCUOUS_MODE)
2480eef4f27bSRobert Mustacchi     {
2481eef4f27bSRobert Mustacchi         sort_mode |= RPM_SORT_USER0_PROM_EN | RPM_SORT_USER0_PROM_VLAN;
2482eef4f27bSRobert Mustacchi     }
2483eef4f27bSRobert Mustacchi 
2484eef4f27bSRobert Mustacchi     switch(user_idx)
2485eef4f27bSRobert Mustacchi     {
2486eef4f27bSRobert Mustacchi         case RX_FILTER_USER_IDX0:
2487eef4f27bSRobert Mustacchi             REG_RD(pdev, rpm.rpm_sort_user0, &val);
2488eef4f27bSRobert Mustacchi 
2489eef4f27bSRobert Mustacchi             REG_WR(pdev, rpm.rpm_sort_user0, 0x00000000);
2490eef4f27bSRobert Mustacchi             REG_WR(pdev, rpm.rpm_sort_user0, sort_mode);
2491eef4f27bSRobert Mustacchi 
2492eef4f27bSRobert Mustacchi             val &= 0xffff;
2493eef4f27bSRobert Mustacchi             val &= ~(1 << user_idx);
2494eef4f27bSRobert Mustacchi 
2495eef4f27bSRobert Mustacchi             sort_mode |= val | RPM_SORT_USER0_ENA;
2496eef4f27bSRobert Mustacchi             REG_WR(pdev, rpm.rpm_sort_user0, sort_mode);
2497eef4f27bSRobert Mustacchi             break;
2498eef4f27bSRobert Mustacchi 
2499eef4f27bSRobert Mustacchi         case RX_FILTER_USER_IDX1:
2500eef4f27bSRobert Mustacchi             REG_RD(pdev, rpm.rpm_sort_user1, &val);
2501eef4f27bSRobert Mustacchi 
2502eef4f27bSRobert Mustacchi             REG_WR(pdev, rpm.rpm_sort_user1, 0x00000000);
2503eef4f27bSRobert Mustacchi             REG_WR(pdev, rpm.rpm_sort_user1, sort_mode);
2504eef4f27bSRobert Mustacchi 
2505eef4f27bSRobert Mustacchi             val &= 0xffff;
2506eef4f27bSRobert Mustacchi             val &= ~(1 << user_idx);
2507eef4f27bSRobert Mustacchi 
2508eef4f27bSRobert Mustacchi             sort_mode |= val | RPM_SORT_USER0_ENA;
2509eef4f27bSRobert Mustacchi             REG_WR(pdev, rpm.rpm_sort_user1, sort_mode);
2510eef4f27bSRobert Mustacchi             break;
2511eef4f27bSRobert Mustacchi 
2512eef4f27bSRobert Mustacchi         case RX_FILTER_USER_IDX2:
2513eef4f27bSRobert Mustacchi             REG_RD(pdev, rpm.rpm_sort_user2, &val);
2514eef4f27bSRobert Mustacchi 
2515eef4f27bSRobert Mustacchi             REG_WR(pdev, rpm.rpm_sort_user2, 0x00000000);
2516eef4f27bSRobert Mustacchi             REG_WR(pdev, rpm.rpm_sort_user2, sort_mode);
2517eef4f27bSRobert Mustacchi 
2518eef4f27bSRobert Mustacchi             val &= 0xffff;
2519eef4f27bSRobert Mustacchi             val &= ~(1 << user_idx);
2520eef4f27bSRobert Mustacchi 
2521eef4f27bSRobert Mustacchi             sort_mode |= val | RPM_SORT_USER0_ENA;
2522eef4f27bSRobert Mustacchi             REG_WR(pdev, rpm.rpm_sort_user2, sort_mode);
2523eef4f27bSRobert Mustacchi             break;
2524eef4f27bSRobert Mustacchi 
2525eef4f27bSRobert Mustacchi         case RX_FILTER_USER_IDX3:
2526eef4f27bSRobert Mustacchi             REG_RD(pdev, rpm.rpm_sort_user3, &val);
2527eef4f27bSRobert Mustacchi 
2528eef4f27bSRobert Mustacchi             REG_WR(pdev, rpm.rpm_sort_user3, 0x00000000);
2529eef4f27bSRobert Mustacchi             REG_WR(pdev, rpm.rpm_sort_user3, sort_mode);
2530eef4f27bSRobert Mustacchi 
2531eef4f27bSRobert Mustacchi             val &= 0xffff;
2532eef4f27bSRobert Mustacchi             val &= ~(1 << user_idx);
2533eef4f27bSRobert Mustacchi 
2534eef4f27bSRobert Mustacchi             sort_mode |= val | RPM_SORT_USER0_ENA;
2535eef4f27bSRobert Mustacchi             REG_WR(pdev, rpm.rpm_sort_user3, sort_mode);
2536eef4f27bSRobert Mustacchi             break;
2537eef4f27bSRobert Mustacchi 
2538eef4f27bSRobert Mustacchi         default:
2539eef4f27bSRobert Mustacchi             DbgBreakMsg("invalid user idx.\n");
2540eef4f27bSRobert Mustacchi 
2541eef4f27bSRobert Mustacchi             break;
2542eef4f27bSRobert Mustacchi     }
2543eef4f27bSRobert Mustacchi 
2544eef4f27bSRobert Mustacchi     /* Set rx_flood for L2. */
2545eef4f27bSRobert Mustacchi     REG_RD_IND(pdev, 0xe0024, &val);
2546eef4f27bSRobert Mustacchi     val &= ~(1 << user_idx);
2547eef4f27bSRobert Mustacchi 
2548eef4f27bSRobert Mustacchi     if(rx_mask & (LM_RX_MASK_ACCEPT_MULTICAST |
2549eef4f27bSRobert Mustacchi                   LM_RX_MASK_ACCEPT_ALL_MULTICAST |
2550eef4f27bSRobert Mustacchi                   LM_RX_MASK_ACCEPT_BROADCAST |
2551eef4f27bSRobert Mustacchi                   LM_RX_MASK_PROMISCUOUS_MODE))
2552eef4f27bSRobert Mustacchi     {
2553eef4f27bSRobert Mustacchi         val |= (1 << user_idx);
2554eef4f27bSRobert Mustacchi     }
2555eef4f27bSRobert Mustacchi 
2556eef4f27bSRobert Mustacchi     REG_WR_IND(pdev, 0xe0024, val);
2557eef4f27bSRobert Mustacchi 
2558eef4f27bSRobert Mustacchi     return LM_STATUS_SUCCESS;
2559eef4f27bSRobert Mustacchi } /* lm_set_rx_mask */
2560eef4f27bSRobert Mustacchi 
2561eef4f27bSRobert Mustacchi 
2562eef4f27bSRobert Mustacchi 
2563eef4f27bSRobert Mustacchi /*******************************************************************************
2564eef4f27bSRobert Mustacchi  * Description:
2565eef4f27bSRobert Mustacchi  *
2566eef4f27bSRobert Mustacchi  * Return:
2567eef4f27bSRobert Mustacchi  ******************************************************************************/
2568eef4f27bSRobert Mustacchi lm_status_t
lm_add_mc(lm_device_t * pdev,u8_t * mc_addr)2569eef4f27bSRobert Mustacchi lm_add_mc(
2570eef4f27bSRobert Mustacchi     lm_device_t *pdev,
2571eef4f27bSRobert Mustacchi     u8_t *mc_addr)
2572eef4f27bSRobert Mustacchi {
2573eef4f27bSRobert Mustacchi     lm_mc_entry_t *mc_entry;
2574eef4f27bSRobert Mustacchi     u32_t cnt;
2575eef4f27bSRobert Mustacchi 
2576eef4f27bSRobert Mustacchi     DbgMessage(pdev, VERBOSE, "### lm_add_mc\n");
2577eef4f27bSRobert Mustacchi 
2578eef4f27bSRobert Mustacchi     for(cnt = 0; cnt < pdev->mc_table.entry_cnt; cnt++)
2579eef4f27bSRobert Mustacchi     {
2580eef4f27bSRobert Mustacchi         mc_entry = &pdev->mc_table.addr_arr[cnt];
2581eef4f27bSRobert Mustacchi 
2582eef4f27bSRobert Mustacchi         if(IS_ETH_ADDRESS_EQUAL(mc_entry->mc_addr, mc_addr))
2583eef4f27bSRobert Mustacchi         {
2584eef4f27bSRobert Mustacchi             mc_entry->ref_cnt++;
2585eef4f27bSRobert Mustacchi 
2586eef4f27bSRobert Mustacchi             return LM_STATUS_SUCCESS;
2587eef4f27bSRobert Mustacchi         }
2588eef4f27bSRobert Mustacchi     }
2589eef4f27bSRobert Mustacchi 
2590eef4f27bSRobert Mustacchi     if(pdev->mc_table.entry_cnt >= LM_MAX_MC_TABLE_SIZE)
2591eef4f27bSRobert Mustacchi     {
2592eef4f27bSRobert Mustacchi         DbgBreakMsg("No entry in MC table\n");
2593eef4f27bSRobert Mustacchi 
2594eef4f27bSRobert Mustacchi         return LM_STATUS_FAILURE;
2595eef4f27bSRobert Mustacchi     }
2596eef4f27bSRobert Mustacchi 
2597eef4f27bSRobert Mustacchi     mc_entry = &pdev->mc_table.addr_arr[pdev->mc_table.entry_cnt];
2598eef4f27bSRobert Mustacchi     pdev->mc_table.entry_cnt++;
2599eef4f27bSRobert Mustacchi 
2600eef4f27bSRobert Mustacchi     mc_entry->ref_cnt = 1;
2601eef4f27bSRobert Mustacchi 
2602eef4f27bSRobert Mustacchi     COPY_ETH_ADDRESS(mc_addr, mc_entry->mc_addr);
2603eef4f27bSRobert Mustacchi 
2604eef4f27bSRobert Mustacchi     (void) lm_set_rx_mask(
2605eef4f27bSRobert Mustacchi         pdev,
2606eef4f27bSRobert Mustacchi         RX_FILTER_USER_IDX0,
2607eef4f27bSRobert Mustacchi         pdev->rx_info.mask[RX_FILTER_USER_IDX0] | LM_RX_MASK_ACCEPT_MULTICAST);
2608eef4f27bSRobert Mustacchi 
2609eef4f27bSRobert Mustacchi     return LM_STATUS_SUCCESS;
2610eef4f27bSRobert Mustacchi } /* lm_add_mc */
2611eef4f27bSRobert Mustacchi 
2612eef4f27bSRobert Mustacchi 
2613eef4f27bSRobert Mustacchi 
2614eef4f27bSRobert Mustacchi /*******************************************************************************
2615eef4f27bSRobert Mustacchi  * Description:
2616eef4f27bSRobert Mustacchi  *
2617eef4f27bSRobert Mustacchi  * Return:
2618eef4f27bSRobert Mustacchi  ******************************************************************************/
2619eef4f27bSRobert Mustacchi lm_status_t
lm_del_mc(lm_device_t * pdev,u8_t * mc_addr)2620eef4f27bSRobert Mustacchi lm_del_mc(
2621eef4f27bSRobert Mustacchi     lm_device_t *pdev,
2622eef4f27bSRobert Mustacchi     u8_t *mc_addr)
2623eef4f27bSRobert Mustacchi {
2624eef4f27bSRobert Mustacchi     lm_mc_entry_t *mc_entry;
2625eef4f27bSRobert Mustacchi     u32_t cnt;
2626eef4f27bSRobert Mustacchi 
2627eef4f27bSRobert Mustacchi     for(cnt = 0; cnt < pdev->mc_table.entry_cnt; cnt++)
2628eef4f27bSRobert Mustacchi     {
2629eef4f27bSRobert Mustacchi         mc_entry = &pdev->mc_table.addr_arr[cnt];
2630eef4f27bSRobert Mustacchi 
2631eef4f27bSRobert Mustacchi         if(IS_ETH_ADDRESS_EQUAL(mc_entry->mc_addr, mc_addr))
2632eef4f27bSRobert Mustacchi         {
2633eef4f27bSRobert Mustacchi             mc_entry->ref_cnt--;
2634eef4f27bSRobert Mustacchi 
2635eef4f27bSRobert Mustacchi             /* No more instance left, remove the address from the table.
2636eef4f27bSRobert Mustacchi              * Move the last entry in the table to the deleted slot. */
2637eef4f27bSRobert Mustacchi             if(mc_entry->ref_cnt == 0)
2638eef4f27bSRobert Mustacchi             {
2639eef4f27bSRobert Mustacchi                 if(pdev->mc_table.entry_cnt > 1)
2640eef4f27bSRobert Mustacchi                 {
2641eef4f27bSRobert Mustacchi                     *mc_entry = pdev->mc_table.addr_arr[pdev->mc_table.entry_cnt-1];
2642eef4f27bSRobert Mustacchi                 }
2643eef4f27bSRobert Mustacchi 
2644eef4f27bSRobert Mustacchi                 pdev->mc_table.entry_cnt--;
2645eef4f27bSRobert Mustacchi 
2646eef4f27bSRobert Mustacchi                 /* Update the receive mask if the table is empty. */
2647eef4f27bSRobert Mustacchi                 if(pdev->mc_table.entry_cnt == 0)
2648eef4f27bSRobert Mustacchi                 {
2649eef4f27bSRobert Mustacchi                     pdev->rx_info.mask[RX_FILTER_USER_IDX0] &=
2650eef4f27bSRobert Mustacchi                             ~LM_RX_MASK_ACCEPT_MULTICAST;
2651eef4f27bSRobert Mustacchi                 }
2652eef4f27bSRobert Mustacchi 
2653eef4f27bSRobert Mustacchi                 (void) lm_set_rx_mask(
2654eef4f27bSRobert Mustacchi                         pdev,
2655eef4f27bSRobert Mustacchi                         RX_FILTER_USER_IDX0,
2656eef4f27bSRobert Mustacchi                         pdev->rx_info.mask[RX_FILTER_USER_IDX0]);
2657eef4f27bSRobert Mustacchi             }
2658eef4f27bSRobert Mustacchi 
2659eef4f27bSRobert Mustacchi             return LM_STATUS_SUCCESS;
2660eef4f27bSRobert Mustacchi         }
2661eef4f27bSRobert Mustacchi     }
2662eef4f27bSRobert Mustacchi 
2663eef4f27bSRobert Mustacchi     DbgBreakMsg("Mc address not in the table\n");
2664eef4f27bSRobert Mustacchi 
2665eef4f27bSRobert Mustacchi     return LM_STATUS_FAILURE;
2666eef4f27bSRobert Mustacchi } /* lm_del_mc */
2667eef4f27bSRobert Mustacchi 
2668eef4f27bSRobert Mustacchi 
2669eef4f27bSRobert Mustacchi 
2670eef4f27bSRobert Mustacchi /*******************************************************************************
2671eef4f27bSRobert Mustacchi  * Description:
2672eef4f27bSRobert Mustacchi  *
2673eef4f27bSRobert Mustacchi  * Return:
2674eef4f27bSRobert Mustacchi  ******************************************************************************/
2675eef4f27bSRobert Mustacchi void
lm_clear_mc(lm_device_t * pdev)2676eef4f27bSRobert Mustacchi lm_clear_mc(lm_device_t *pdev)
2677eef4f27bSRobert Mustacchi {
2678eef4f27bSRobert Mustacchi     DbgMessage(pdev, VERBOSE, "### lm_clear_mc\n");
2679eef4f27bSRobert Mustacchi 
2680eef4f27bSRobert Mustacchi     pdev->mc_table.entry_cnt = 0;
2681eef4f27bSRobert Mustacchi 
2682eef4f27bSRobert Mustacchi     (void) lm_set_rx_mask(
2683eef4f27bSRobert Mustacchi         pdev,
2684eef4f27bSRobert Mustacchi         RX_FILTER_USER_IDX0,
2685eef4f27bSRobert Mustacchi         pdev->rx_info.mask[RX_FILTER_USER_IDX0] & ~LM_RX_MASK_ACCEPT_MULTICAST);
2686eef4f27bSRobert Mustacchi } /* lm_clear_mc */
2687eef4f27bSRobert Mustacchi 
2688eef4f27bSRobert Mustacchi 
2689eef4f27bSRobert Mustacchi 
2690eef4f27bSRobert Mustacchi /*******************************************************************************
2691eef4f27bSRobert Mustacchi  * Description:
2692eef4f27bSRobert Mustacchi  *
2693eef4f27bSRobert Mustacchi  * Return:
2694eef4f27bSRobert Mustacchi  ******************************************************************************/
2695eef4f27bSRobert Mustacchi lm_status_t
lm_get_stats(lm_device_t * pdev,lm_stats_t stats_type,u64_t * stats_cnt)2696eef4f27bSRobert Mustacchi lm_get_stats(
2697eef4f27bSRobert Mustacchi     lm_device_t *pdev,
2698eef4f27bSRobert Mustacchi     lm_stats_t stats_type,
2699eef4f27bSRobert Mustacchi     u64_t *stats_cnt)
2700eef4f27bSRobert Mustacchi {
2701eef4f27bSRobert Mustacchi     volatile statistics_block_t *sb;
2702eef4f27bSRobert Mustacchi     lm_status_t lm_status;
2703eef4f27bSRobert Mustacchi     lm_u64_t *stats;
2704eef4f27bSRobert Mustacchi     u32_t reg_val;
2705eef4f27bSRobert Mustacchi     u32_t val;
2706eef4f27bSRobert Mustacchi 
2707eef4f27bSRobert Mustacchi     //
2708eef4f27bSRobert Mustacchi     // The fix of CQ#29454 caused CQ#30307 -
2709eef4f27bSRobert Mustacchi     // Bacs: Bogus counters on 5708 under statistics tab
2710eef4f27bSRobert Mustacchi     // So far, Windows never see CQ#29454 problem.
2711eef4f27bSRobert Mustacchi     // Remove the fix right now
2712eef4f27bSRobert Mustacchi     //
2713eef4f27bSRobert Mustacchi 
2714eef4f27bSRobert Mustacchi     /* CQ#29454 - statistics corruption. */
2715eef4f27bSRobert Mustacchi     //REG_RD(pdev, hc.hc_stats_ticks, &val);
2716eef4f27bSRobert Mustacchi     //REG_WR(pdev, hc.hc_stats_ticks, 0);
2717eef4f27bSRobert Mustacchi 
2718eef4f27bSRobert Mustacchi     REG_WR(pdev, hc.hc_command, HC_COMMAND_STATS_NOW);
2719eef4f27bSRobert Mustacchi     REG_RD(pdev, hc.hc_command, &reg_val);
2720eef4f27bSRobert Mustacchi     mm_wait(pdev, 5);
2721eef4f27bSRobert Mustacchi 
2722eef4f27bSRobert Mustacchi     lm_status = LM_STATUS_SUCCESS;
2723eef4f27bSRobert Mustacchi     sb = pdev->vars.stats_virt;
2724eef4f27bSRobert Mustacchi     stats = (lm_u64_t *) stats_cnt;
2725eef4f27bSRobert Mustacchi 
2726eef4f27bSRobert Mustacchi     switch(stats_type)
2727eef4f27bSRobert Mustacchi     {
2728eef4f27bSRobert Mustacchi         case LM_STATS_FRAMES_XMITTED_OK:
2729eef4f27bSRobert Mustacchi             stats->as_u32.low = sb->stat_IfHCOutUcastPkts_lo;
2730eef4f27bSRobert Mustacchi             stats->as_u32.high = sb->stat_IfHCOutUcastPkts_hi;
2731eef4f27bSRobert Mustacchi 
2732eef4f27bSRobert Mustacchi             LM_INC64(stats, sb->stat_IfHCOutMulticastPkts_lo);
2733eef4f27bSRobert Mustacchi             stats->as_u32.high += sb->stat_IfHCOutMulticastPkts_hi;
2734eef4f27bSRobert Mustacchi 
2735eef4f27bSRobert Mustacchi             LM_INC64(stats, sb->stat_IfHCOutBroadcastPkts_lo);
2736eef4f27bSRobert Mustacchi             stats->as_u32.high += sb->stat_IfHCOutBroadcastPkts_hi;
2737eef4f27bSRobert Mustacchi             break;
2738eef4f27bSRobert Mustacchi 
2739eef4f27bSRobert Mustacchi         case LM_STATS_FRAMES_RECEIVED_OK:
2740eef4f27bSRobert Mustacchi             stats->as_u32.low = sb->stat_IfHCInUcastPkts_lo;
2741eef4f27bSRobert Mustacchi             stats->as_u32.high = sb->stat_IfHCInUcastPkts_hi;
2742eef4f27bSRobert Mustacchi 
2743eef4f27bSRobert Mustacchi             LM_INC64(stats, sb->stat_IfHCInMulticastPkts_lo);
2744eef4f27bSRobert Mustacchi             stats->as_u32.high += sb->stat_IfHCInMulticastPkts_hi;
2745eef4f27bSRobert Mustacchi 
2746eef4f27bSRobert Mustacchi             LM_INC64(stats, sb->stat_IfHCInBroadcastPkts_lo);
2747eef4f27bSRobert Mustacchi             stats->as_u32.high += sb->stat_IfHCInBroadcastPkts_hi;
2748eef4f27bSRobert Mustacchi             REG_RD_IND(
2749eef4f27bSRobert Mustacchi                 pdev,
2750*55fea89dSDan Cross                 OFFSETOF(reg_space_t,
2751eef4f27bSRobert Mustacchi                          com.com_scratch[0])+
2752eef4f27bSRobert Mustacchi                          COM_HSI_OFFSETOFF(com_l2_iscsi_no_buffer),
2753eef4f27bSRobert Mustacchi                          &val);
2754eef4f27bSRobert Mustacchi             if((stats->as_u32.high == 0 && stats->as_u32.low) &&
2755eef4f27bSRobert Mustacchi                (stats->as_u32.low < val))
2756eef4f27bSRobert Mustacchi             {
2757eef4f27bSRobert Mustacchi                 /* due to asynchrous nature of reading the counters
2758eef4f27bSRobert Mustacchi                  * from status block and reading the counters from
2759eef4f27bSRobert Mustacchi                  * chip scratchpad mem, it is possible that the values
2760eef4f27bSRobert Mustacchi                  * are out of syn */
2761eef4f27bSRobert Mustacchi                 stats->as_u32.low = 0;
2762eef4f27bSRobert Mustacchi             }
2763eef4f27bSRobert Mustacchi             else
2764eef4f27bSRobert Mustacchi             {
2765eef4f27bSRobert Mustacchi                 LM_DEC64(stats, val);
2766eef4f27bSRobert Mustacchi             }
2767eef4f27bSRobert Mustacchi 
2768eef4f27bSRobert Mustacchi             REG_RD_IND(
2769eef4f27bSRobert Mustacchi                 pdev,
2770*55fea89dSDan Cross                 OFFSETOF(reg_space_t,
2771eef4f27bSRobert Mustacchi                          com.com_scratch[0])+
2772eef4f27bSRobert Mustacchi                          COM_HSI_OFFSETOFF(com_l2_no_buffer),
2773eef4f27bSRobert Mustacchi                          &val);
2774eef4f27bSRobert Mustacchi             if((stats->as_u32.high == 0 && stats->as_u32.low) &&
2775eef4f27bSRobert Mustacchi                (stats->as_u32.low < val))
2776eef4f27bSRobert Mustacchi             {
2777eef4f27bSRobert Mustacchi                 /* due to asynchrous nature of reading the counters
2778eef4f27bSRobert Mustacchi                  * from status block and reading the counters from
2779eef4f27bSRobert Mustacchi                  * chip scratchpad mem, it is possible that the values
2780eef4f27bSRobert Mustacchi                  * are out of syn */
2781eef4f27bSRobert Mustacchi                 stats->as_u32.low = 0;
2782eef4f27bSRobert Mustacchi             }
2783eef4f27bSRobert Mustacchi             else
2784eef4f27bSRobert Mustacchi             {
2785eef4f27bSRobert Mustacchi                 LM_DEC64(stats, val);
2786eef4f27bSRobert Mustacchi             }
2787eef4f27bSRobert Mustacchi             break;
2788eef4f27bSRobert Mustacchi 
2789eef4f27bSRobert Mustacchi         case LM_STATS_ERRORED_RECEIVE_CNT:
2790eef4f27bSRobert Mustacchi             stats->as_u32.low = pdev->rx_info.stats.err;
2791eef4f27bSRobert Mustacchi             stats->as_u32.high = 0;
2792eef4f27bSRobert Mustacchi             break;
2793eef4f27bSRobert Mustacchi 
2794eef4f27bSRobert Mustacchi         case LM_STATS_RCV_CRC_ERROR:
2795eef4f27bSRobert Mustacchi             stats->as_u32.low = sb->stat_Dot3StatsFCSErrors;
2796eef4f27bSRobert Mustacchi             stats->as_u32.high = 0;
2797eef4f27bSRobert Mustacchi             break;
2798eef4f27bSRobert Mustacchi 
2799eef4f27bSRobert Mustacchi         case LM_STATS_ALIGNMENT_ERROR:
2800eef4f27bSRobert Mustacchi             stats->as_u32.low = sb->stat_Dot3StatsAlignmentErrors;
2801eef4f27bSRobert Mustacchi             stats->as_u32.high = 0;
2802eef4f27bSRobert Mustacchi             break;
2803eef4f27bSRobert Mustacchi 
2804eef4f27bSRobert Mustacchi         case LM_STATS_SINGLE_COLLISION_FRAMES:
2805eef4f27bSRobert Mustacchi             stats->as_u32.low = sb->stat_Dot3StatsSingleCollisionFrames;
2806eef4f27bSRobert Mustacchi             stats->as_u32.high = 0;
2807eef4f27bSRobert Mustacchi             break;
2808eef4f27bSRobert Mustacchi 
2809eef4f27bSRobert Mustacchi         case LM_STATS_MULTIPLE_COLLISION_FRAMES:
2810eef4f27bSRobert Mustacchi             stats->as_u32.low = sb->stat_Dot3StatsMultipleCollisionFrames;
2811eef4f27bSRobert Mustacchi             stats->as_u32.high = 0;
2812eef4f27bSRobert Mustacchi             break;
2813eef4f27bSRobert Mustacchi 
2814eef4f27bSRobert Mustacchi         case LM_STATS_FRAMES_DEFERRED:
2815eef4f27bSRobert Mustacchi             stats->as_u32.low = sb->stat_Dot3StatsDeferredTransmissions;
2816eef4f27bSRobert Mustacchi             stats->as_u32.high = 0;
2817eef4f27bSRobert Mustacchi             break;
2818eef4f27bSRobert Mustacchi 
2819eef4f27bSRobert Mustacchi         case LM_STATS_MAX_COLLISIONS:
2820eef4f27bSRobert Mustacchi             stats->as_u32.low = sb->stat_Dot3StatsExcessiveCollisions;
2821eef4f27bSRobert Mustacchi             break;
2822eef4f27bSRobert Mustacchi 
2823eef4f27bSRobert Mustacchi         case LM_STATS_UNICAST_FRAMES_XMIT:
2824eef4f27bSRobert Mustacchi             stats->as_u32.low = sb->stat_IfHCOutUcastPkts_lo;
2825eef4f27bSRobert Mustacchi             stats->as_u32.high = sb->stat_IfHCOutUcastPkts_hi;
2826eef4f27bSRobert Mustacchi             break;
2827eef4f27bSRobert Mustacchi 
2828eef4f27bSRobert Mustacchi         case LM_STATS_MULTICAST_FRAMES_XMIT:
2829eef4f27bSRobert Mustacchi             stats->as_u32.low = sb->stat_IfHCOutMulticastPkts_lo;
2830eef4f27bSRobert Mustacchi             stats->as_u32.high = sb->stat_IfHCOutMulticastPkts_hi;
2831eef4f27bSRobert Mustacchi             break;
2832eef4f27bSRobert Mustacchi 
2833eef4f27bSRobert Mustacchi         case LM_STATS_BROADCAST_FRAMES_XMIT:
2834eef4f27bSRobert Mustacchi             stats->as_u32.low = sb->stat_IfHCOutBroadcastPkts_lo;
2835eef4f27bSRobert Mustacchi             stats->as_u32.high = sb->stat_IfHCOutBroadcastPkts_hi;
2836eef4f27bSRobert Mustacchi             break;
2837eef4f27bSRobert Mustacchi 
2838eef4f27bSRobert Mustacchi         case LM_STATS_UNICAST_FRAMES_RCV:
2839eef4f27bSRobert Mustacchi             stats->as_u32.low = sb->stat_IfHCInUcastPkts_lo;
2840eef4f27bSRobert Mustacchi             stats->as_u32.high = sb->stat_IfHCInUcastPkts_hi;
2841eef4f27bSRobert Mustacchi             REG_RD_IND(
2842eef4f27bSRobert Mustacchi                 pdev,
2843*55fea89dSDan Cross                 OFFSETOF(reg_space_t,
2844eef4f27bSRobert Mustacchi                          com.com_scratch[0])+
2845eef4f27bSRobert Mustacchi                          COM_HSI_OFFSETOFF(com_unicast_no_buffer),
2846eef4f27bSRobert Mustacchi                          &val);
2847eef4f27bSRobert Mustacchi             if((stats->as_u32.high == 0 && stats->as_u32.low) &&
2848eef4f27bSRobert Mustacchi                (stats->as_u32.low < val))
2849eef4f27bSRobert Mustacchi             {
2850eef4f27bSRobert Mustacchi                 /* due to asynchrous nature of reading the counters
2851eef4f27bSRobert Mustacchi                  * from status block and reading the counters from
2852eef4f27bSRobert Mustacchi                  * chip scratchpad mem, it is possible that the values
2853eef4f27bSRobert Mustacchi                  * are out of syn */
2854eef4f27bSRobert Mustacchi                 stats->as_u32.low = 0;
2855eef4f27bSRobert Mustacchi             }
2856eef4f27bSRobert Mustacchi             else
2857eef4f27bSRobert Mustacchi             {
2858eef4f27bSRobert Mustacchi                 LM_DEC64(stats, val);
2859eef4f27bSRobert Mustacchi             }
2860eef4f27bSRobert Mustacchi             break;
2861eef4f27bSRobert Mustacchi 
2862eef4f27bSRobert Mustacchi         case LM_STATS_MULTICAST_FRAMES_RCV:
2863eef4f27bSRobert Mustacchi             stats->as_u32.low = sb->stat_IfHCInMulticastPkts_lo;
2864eef4f27bSRobert Mustacchi             stats->as_u32.high = sb->stat_IfHCInMulticastPkts_hi;
2865eef4f27bSRobert Mustacchi             REG_RD_IND(
2866eef4f27bSRobert Mustacchi                 pdev,
2867*55fea89dSDan Cross                 OFFSETOF(reg_space_t,
2868eef4f27bSRobert Mustacchi                          com.com_scratch[0])+
2869eef4f27bSRobert Mustacchi                          COM_HSI_OFFSETOFF(com_mcast_no_buffer),
2870eef4f27bSRobert Mustacchi                          &val);
2871*55fea89dSDan Cross 
2872eef4f27bSRobert Mustacchi             if((stats->as_u32.high == 0 && stats->as_u32.low) &&
2873eef4f27bSRobert Mustacchi                (stats->as_u32.low < val))
2874eef4f27bSRobert Mustacchi             {
2875eef4f27bSRobert Mustacchi                 /* due to asynchrous nature of reading the counters
2876eef4f27bSRobert Mustacchi                  * from status block and reading the counters from
2877eef4f27bSRobert Mustacchi                  * chip scratchpad mem, it is possible that the values
2878eef4f27bSRobert Mustacchi                  * are out of syn */
2879eef4f27bSRobert Mustacchi                 stats->as_u32.low = 0;
2880eef4f27bSRobert Mustacchi             }
2881eef4f27bSRobert Mustacchi             else
2882eef4f27bSRobert Mustacchi             {
2883eef4f27bSRobert Mustacchi                 LM_DEC64(stats, val);
2884eef4f27bSRobert Mustacchi             }
2885eef4f27bSRobert Mustacchi             break;
2886eef4f27bSRobert Mustacchi 
2887eef4f27bSRobert Mustacchi         case LM_STATS_BROADCAST_FRAMES_RCV:
2888eef4f27bSRobert Mustacchi             stats->as_u32.low = sb->stat_IfHCInBroadcastPkts_lo;
2889eef4f27bSRobert Mustacchi             stats->as_u32.high = sb->stat_IfHCInBroadcastPkts_hi;
2890eef4f27bSRobert Mustacchi             REG_RD_IND(
2891eef4f27bSRobert Mustacchi                 pdev,
2892*55fea89dSDan Cross                 OFFSETOF(reg_space_t,
2893eef4f27bSRobert Mustacchi                          com.com_scratch[0])+
2894eef4f27bSRobert Mustacchi                          COM_HSI_OFFSETOFF(com_bcast_no_buffer),
2895eef4f27bSRobert Mustacchi                          &val);
2896eef4f27bSRobert Mustacchi             if((stats->as_u32.high == 0 && stats->as_u32.low) &&
2897eef4f27bSRobert Mustacchi                (stats->as_u32.low < val))
2898eef4f27bSRobert Mustacchi             {
2899eef4f27bSRobert Mustacchi                 /* due to asynchrous nature of reading the counters
2900eef4f27bSRobert Mustacchi                  * from status block and reading the counters from
2901eef4f27bSRobert Mustacchi                  * chip scratchpad mem, it is possible that the values
2902eef4f27bSRobert Mustacchi                  * are out of syn */
2903eef4f27bSRobert Mustacchi                 stats->as_u32.low = 0;
2904eef4f27bSRobert Mustacchi             }
2905eef4f27bSRobert Mustacchi             else
2906eef4f27bSRobert Mustacchi             {
2907eef4f27bSRobert Mustacchi                 LM_DEC64(stats, val);
2908eef4f27bSRobert Mustacchi             }
2909eef4f27bSRobert Mustacchi             break;
2910eef4f27bSRobert Mustacchi 
2911eef4f27bSRobert Mustacchi         case LM_STATS_ERRORED_TRANSMIT_CNT:
2912eef4f27bSRobert Mustacchi         case LM_STATS_RCV_OVERRUN:
2913eef4f27bSRobert Mustacchi         case LM_STATS_XMIT_UNDERRUN:
2914eef4f27bSRobert Mustacchi             /* These counters are always zero. */
2915eef4f27bSRobert Mustacchi             stats->as_u32.low = 0;
2916eef4f27bSRobert Mustacchi             stats->as_u32.high = 0;
2917eef4f27bSRobert Mustacchi             break;
2918eef4f27bSRobert Mustacchi 
2919eef4f27bSRobert Mustacchi         case LM_STATS_RCV_NO_BUFFER_DROP:
2920eef4f27bSRobert Mustacchi             /* com_no_buffer */
2921eef4f27bSRobert Mustacchi             REG_RD_IND(
2922eef4f27bSRobert Mustacchi                 pdev,
2923eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, com.com_scratch[0])+COM_HSI_OFFSETOFF(com_unicast_no_buffer),
2924eef4f27bSRobert Mustacchi                 &val);
2925eef4f27bSRobert Mustacchi             stats->as_u32.low = val;
2926eef4f27bSRobert Mustacchi             REG_RD_IND(
2927eef4f27bSRobert Mustacchi                 pdev,
2928eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, com.com_scratch[0])+COM_HSI_OFFSETOFF(com_mcast_no_buffer),
2929eef4f27bSRobert Mustacchi                 &val);
2930eef4f27bSRobert Mustacchi             stats->as_u32.low += val;
2931eef4f27bSRobert Mustacchi             REG_RD_IND(
2932eef4f27bSRobert Mustacchi                 pdev,
2933eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, com.com_scratch[0])+COM_HSI_OFFSETOFF(com_bcast_no_buffer),
2934eef4f27bSRobert Mustacchi                 &val);
2935eef4f27bSRobert Mustacchi             stats->as_u32.low += val;
2936eef4f27bSRobert Mustacchi 
2937eef4f27bSRobert Mustacchi             stats->as_u32.high = 0;
2938eef4f27bSRobert Mustacchi             break;
2939eef4f27bSRobert Mustacchi 
2940eef4f27bSRobert Mustacchi         case LM_STATS_BYTES_RCV:
2941eef4f27bSRobert Mustacchi             stats->as_u32.low = sb->stat_IfHCInOctets_lo;
2942eef4f27bSRobert Mustacchi             stats->as_u32.high = sb->stat_IfHCInOctets_hi;
2943eef4f27bSRobert Mustacchi             break;
2944eef4f27bSRobert Mustacchi 
2945eef4f27bSRobert Mustacchi         case LM_STATS_BYTES_XMIT:
2946eef4f27bSRobert Mustacchi             stats->as_u32.low = sb->stat_IfHCOutOctets_lo;
2947eef4f27bSRobert Mustacchi             stats->as_u32.high = sb->stat_IfHCOutOctets_hi;
2948eef4f27bSRobert Mustacchi             break;
2949eef4f27bSRobert Mustacchi 
2950eef4f27bSRobert Mustacchi         case LM_STATS_IF_IN_DISCARDS:
2951eef4f27bSRobert Mustacchi             /* com_no_buffer */
2952eef4f27bSRobert Mustacchi             REG_RD_IND(
2953eef4f27bSRobert Mustacchi                 pdev,
2954eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, com.com_scratch[0])+COM_HSI_OFFSETOFF(com_unicast_no_buffer),
2955eef4f27bSRobert Mustacchi                 &val);
2956eef4f27bSRobert Mustacchi             stats->as_u32.low = val;
2957eef4f27bSRobert Mustacchi             REG_RD_IND(
2958eef4f27bSRobert Mustacchi                 pdev,
2959eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, com.com_scratch[0])+COM_HSI_OFFSETOFF(com_mcast_no_buffer),
2960eef4f27bSRobert Mustacchi                 &val);
2961eef4f27bSRobert Mustacchi             stats->as_u32.low += val;
2962eef4f27bSRobert Mustacchi             REG_RD_IND(
2963eef4f27bSRobert Mustacchi                 pdev,
2964eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, com.com_scratch[0])+COM_HSI_OFFSETOFF(com_bcast_no_buffer),
2965eef4f27bSRobert Mustacchi                 &val);
2966eef4f27bSRobert Mustacchi             stats->as_u32.low += val;
2967eef4f27bSRobert Mustacchi             stats->as_u32.low += sb->stat_Dot3StatsFCSErrors;
2968eef4f27bSRobert Mustacchi 
2969eef4f27bSRobert Mustacchi             stats->as_u32.high = 0;
2970eef4f27bSRobert Mustacchi             break;
2971eef4f27bSRobert Mustacchi 
2972eef4f27bSRobert Mustacchi         case LM_STATS_XMIT_DISCARDS:
2973eef4f27bSRobert Mustacchi         case LM_STATS_IF_IN_ERRORS:
2974eef4f27bSRobert Mustacchi         case LM_STATS_IF_OUT_ERRORS:
2975eef4f27bSRobert Mustacchi             stats->as_u32.low = 0;
2976eef4f27bSRobert Mustacchi             stats->as_u32.high = 0;
2977eef4f27bSRobert Mustacchi             break;
2978eef4f27bSRobert Mustacchi 
2979eef4f27bSRobert Mustacchi         case LM_STATS_DIRECTED_BYTES_RCV:
2980eef4f27bSRobert Mustacchi             /* rxp_unicast_bytes_rcvd */
2981eef4f27bSRobert Mustacchi             REG_RD_IND(
2982eef4f27bSRobert Mustacchi                 pdev,
2983eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, rxp.rxp_scratch[0])+RXP_HSI_OFFSETOFF(rxp_unicast_bytes_rcvd)+4,
2984eef4f27bSRobert Mustacchi                 &stats->as_u32.low);
2985eef4f27bSRobert Mustacchi             REG_RD_IND(
2986eef4f27bSRobert Mustacchi                 pdev,
2987eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, rxp.rxp_scratch[0])+RXP_HSI_OFFSETOFF(rxp_unicast_bytes_rcvd),
2988eef4f27bSRobert Mustacchi                 &stats->as_u32.high);
2989eef4f27bSRobert Mustacchi             break;
2990eef4f27bSRobert Mustacchi 
2991eef4f27bSRobert Mustacchi         case LM_STATS_MULTICAST_BYTES_RCV:
2992eef4f27bSRobert Mustacchi             /* rxp_multicast_bytes_rcvd */
2993eef4f27bSRobert Mustacchi             REG_RD_IND(
2994eef4f27bSRobert Mustacchi                 pdev,
2995eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, rxp.rxp_scratch[0])+RXP_HSI_OFFSETOFF(rxp_multicast_bytes_rcvd)+4,
2996eef4f27bSRobert Mustacchi                 &stats->as_u32.low);
2997eef4f27bSRobert Mustacchi             REG_RD_IND(
2998eef4f27bSRobert Mustacchi                 pdev,
2999eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, rxp.rxp_scratch[0])+RXP_HSI_OFFSETOFF(rxp_multicast_bytes_rcvd),
3000eef4f27bSRobert Mustacchi                 &stats->as_u32.high);
3001eef4f27bSRobert Mustacchi             break;
3002eef4f27bSRobert Mustacchi 
3003eef4f27bSRobert Mustacchi         case LM_STATS_BROADCAST_BYTES_RCV:
3004eef4f27bSRobert Mustacchi             /* rxp_broadcast_bytes_rcvd */
3005eef4f27bSRobert Mustacchi             REG_RD_IND(
3006eef4f27bSRobert Mustacchi                 pdev,
3007eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, rxp.rxp_scratch[0])+RXP_HSI_OFFSETOFF(rxp_broadcast_bytes_rcvd)+4,
3008eef4f27bSRobert Mustacchi                 &stats->as_u32.low);
3009eef4f27bSRobert Mustacchi             REG_RD_IND(
3010eef4f27bSRobert Mustacchi                 pdev,
3011eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, rxp.rxp_scratch[0])+RXP_HSI_OFFSETOFF(rxp_broadcast_bytes_rcvd),
3012eef4f27bSRobert Mustacchi                 &stats->as_u32.high);
3013eef4f27bSRobert Mustacchi             break;
3014eef4f27bSRobert Mustacchi 
3015eef4f27bSRobert Mustacchi         case LM_STATS_DIRECTED_BYTES_XMIT:
3016eef4f27bSRobert Mustacchi             /* unicast_bytes_xmit_lo */
3017eef4f27bSRobert Mustacchi             REG_RD_IND(
3018eef4f27bSRobert Mustacchi                 pdev,
3019eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, tpat.tpat_scratch[0])+TPAT_HSI_OFFSETOFF(unicast_bytes_xmit)+4,
3020*55fea89dSDan Cross                 &stats->as_u32.low);
3021eef4f27bSRobert Mustacchi             REG_RD_IND(
3022eef4f27bSRobert Mustacchi                 pdev,
3023eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, tpat.tpat_scratch[0])+TPAT_HSI_OFFSETOFF(unicast_bytes_xmit),
3024eef4f27bSRobert Mustacchi                 &stats->as_u32.high);
3025eef4f27bSRobert Mustacchi             break;
3026eef4f27bSRobert Mustacchi 
3027eef4f27bSRobert Mustacchi         case LM_STATS_MULTICAST_BYTES_XMIT:
3028eef4f27bSRobert Mustacchi             /* multicast_bytes_xmit */
3029eef4f27bSRobert Mustacchi             REG_RD_IND(
3030eef4f27bSRobert Mustacchi                 pdev,
3031eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, tpat.tpat_scratch[0])+TPAT_HSI_OFFSETOFF(multicast_bytes_xmit)+4,
3032eef4f27bSRobert Mustacchi                 &stats->as_u32.low);
3033eef4f27bSRobert Mustacchi             REG_RD_IND(
3034eef4f27bSRobert Mustacchi                 pdev,
3035eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, tpat.tpat_scratch[0])+TPAT_HSI_OFFSETOFF(multicast_bytes_xmit),
3036eef4f27bSRobert Mustacchi                 &stats->as_u32.high);
3037eef4f27bSRobert Mustacchi             break;
3038eef4f27bSRobert Mustacchi 
3039eef4f27bSRobert Mustacchi         case LM_STATS_BROADCAST_BYTES_XMIT:
3040eef4f27bSRobert Mustacchi             /* broadcast_bytes_xmit */
3041eef4f27bSRobert Mustacchi             REG_RD_IND(
3042eef4f27bSRobert Mustacchi                 pdev,
3043eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, tpat.tpat_scratch[0])+TPAT_HSI_OFFSETOFF(broadcast_bytes_xmit)+4,
3044eef4f27bSRobert Mustacchi                 &stats->as_u32.low);
3045eef4f27bSRobert Mustacchi             REG_RD_IND(
3046eef4f27bSRobert Mustacchi                 pdev,
3047eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, tpat.tpat_scratch[0])+TPAT_HSI_OFFSETOFF(broadcast_bytes_xmit),
3048eef4f27bSRobert Mustacchi                 &stats->as_u32.high);
3049eef4f27bSRobert Mustacchi             break;
3050eef4f27bSRobert Mustacchi 
3051eef4f27bSRobert Mustacchi         default:
3052eef4f27bSRobert Mustacchi             stats->as_u32.low = 0;
3053eef4f27bSRobert Mustacchi             stats->as_u32.high = 0;
3054eef4f27bSRobert Mustacchi 
3055eef4f27bSRobert Mustacchi             lm_status = LM_STATUS_INVALID_PARAMETER;
3056eef4f27bSRobert Mustacchi             break;
3057eef4f27bSRobert Mustacchi     }
3058eef4f27bSRobert Mustacchi 
3059eef4f27bSRobert Mustacchi     //REG_WR(pdev, hc.hc_stats_ticks, val);
3060eef4f27bSRobert Mustacchi 
3061eef4f27bSRobert Mustacchi     return lm_status;
3062eef4f27bSRobert Mustacchi } /* lm_get_stats */
3063eef4f27bSRobert Mustacchi 
3064eef4f27bSRobert Mustacchi 
3065eef4f27bSRobert Mustacchi 
3066eef4f27bSRobert Mustacchi /*******************************************************************************
3067eef4f27bSRobert Mustacchi  * Description:
3068eef4f27bSRobert Mustacchi  *
3069eef4f27bSRobert Mustacchi  * Return:
3070eef4f27bSRobert Mustacchi  ******************************************************************************/
3071eef4f27bSRobert Mustacchi STATIC lm_nwuf_t *
find_nwuf(lm_nwuf_list_t * nwuf_list,u32_t mask_size,u8_t * byte_mask,u8_t * pattern,u32_t max_nwuf_cnt)3072eef4f27bSRobert Mustacchi find_nwuf(
3073eef4f27bSRobert Mustacchi     lm_nwuf_list_t *nwuf_list,
3074eef4f27bSRobert Mustacchi     u32_t mask_size,
3075eef4f27bSRobert Mustacchi     u8_t *byte_mask,
3076eef4f27bSRobert Mustacchi     u8_t *pattern,
3077eef4f27bSRobert Mustacchi     u32_t max_nwuf_cnt)
3078eef4f27bSRobert Mustacchi {
3079eef4f27bSRobert Mustacchi     lm_nwuf_t *nwuf;
3080eef4f27bSRobert Mustacchi     u8_t found;
3081eef4f27bSRobert Mustacchi     u32_t idx;
3082eef4f27bSRobert Mustacchi     u32_t j;
3083eef4f27bSRobert Mustacchi     u32_t k;
3084*55fea89dSDan Cross 
3085eef4f27bSRobert Mustacchi     for(idx = 0; idx < max_nwuf_cnt; idx++)
3086eef4f27bSRobert Mustacchi     {
3087eef4f27bSRobert Mustacchi         nwuf = &nwuf_list->nwuf_arr[idx];
3088eef4f27bSRobert Mustacchi 
3089eef4f27bSRobert Mustacchi         if((nwuf->size&0xffff) != mask_size)
3090eef4f27bSRobert Mustacchi         {
3091eef4f27bSRobert Mustacchi             continue;
3092eef4f27bSRobert Mustacchi         }
3093eef4f27bSRobert Mustacchi 
3094eef4f27bSRobert Mustacchi         found = TRUE;
3095eef4f27bSRobert Mustacchi         for(j = 0; j < mask_size && found == TRUE; j++)
3096eef4f27bSRobert Mustacchi         {
3097eef4f27bSRobert Mustacchi             if(nwuf->mask[j] != byte_mask[j])
3098eef4f27bSRobert Mustacchi             {
3099eef4f27bSRobert Mustacchi                 found = FALSE;
3100eef4f27bSRobert Mustacchi                 break;
3101eef4f27bSRobert Mustacchi             }
3102eef4f27bSRobert Mustacchi 
3103eef4f27bSRobert Mustacchi             for(k = 0; k < 8; k++)
3104eef4f27bSRobert Mustacchi             {
3105eef4f27bSRobert Mustacchi                 if((byte_mask[j] & (1 << k)) &&
3106eef4f27bSRobert Mustacchi                     (nwuf->pattern[j*8 + k] != pattern[j*8 + k]))
3107eef4f27bSRobert Mustacchi                 {
3108eef4f27bSRobert Mustacchi                     found = FALSE;
3109eef4f27bSRobert Mustacchi                     break;
3110eef4f27bSRobert Mustacchi                 }
3111eef4f27bSRobert Mustacchi             }
3112eef4f27bSRobert Mustacchi         }
3113eef4f27bSRobert Mustacchi 
3114eef4f27bSRobert Mustacchi         if(found)
3115eef4f27bSRobert Mustacchi         {
3116eef4f27bSRobert Mustacchi             return nwuf;
3117eef4f27bSRobert Mustacchi         }
3118eef4f27bSRobert Mustacchi     }
3119eef4f27bSRobert Mustacchi 
3120eef4f27bSRobert Mustacchi     return NULL;
3121eef4f27bSRobert Mustacchi } /* find_nwuf */
3122eef4f27bSRobert Mustacchi 
3123eef4f27bSRobert Mustacchi 
3124eef4f27bSRobert Mustacchi 
3125eef4f27bSRobert Mustacchi /*******************************************************************************
3126eef4f27bSRobert Mustacchi  * Description:
3127eef4f27bSRobert Mustacchi  *
3128eef4f27bSRobert Mustacchi  * Return:
3129eef4f27bSRobert Mustacchi  ******************************************************************************/
3130eef4f27bSRobert Mustacchi lm_status_t
lm_add_nwuf(lm_device_t * pdev,u32_t pattern_size,u32_t mask_size,u8_t * byte_mask,u8_t * pattern)3131eef4f27bSRobert Mustacchi lm_add_nwuf(
3132eef4f27bSRobert Mustacchi     lm_device_t *pdev,
3133eef4f27bSRobert Mustacchi     u32_t pattern_size,
3134eef4f27bSRobert Mustacchi     u32_t mask_size,
3135eef4f27bSRobert Mustacchi     u8_t *byte_mask,
3136eef4f27bSRobert Mustacchi     u8_t *pattern)
3137eef4f27bSRobert Mustacchi {
3138eef4f27bSRobert Mustacchi     lm_nwuf_t *nwuf;
3139eef4f27bSRobert Mustacchi     u32_t idx;
3140eef4f27bSRobert Mustacchi /*
3141eef4f27bSRobert Mustacchi     u32_t i;
3142eef4f27bSRobert Mustacchi */
3143eef4f27bSRobert Mustacchi     u32_t j;
3144eef4f27bSRobert Mustacchi     u32_t k;
3145eef4f27bSRobert Mustacchi     u32_t l;
3146eef4f27bSRobert Mustacchi     u32_t combind_size;
3147eef4f27bSRobert Mustacchi     u32_t max_nwuf_cnt;
3148eef4f27bSRobert Mustacchi 
3149eef4f27bSRobert Mustacchi     if(CHIP_NUM(pdev) == CHIP_NUM_5709)
3150eef4f27bSRobert Mustacchi     {
3151eef4f27bSRobert Mustacchi         max_nwuf_cnt = LM_MAX_NWUF_CNT_5709;
3152eef4f27bSRobert Mustacchi     }
3153eef4f27bSRobert Mustacchi     else
3154eef4f27bSRobert Mustacchi     {
3155eef4f27bSRobert Mustacchi         max_nwuf_cnt = LM_MAX_NWUF_CNT;
3156eef4f27bSRobert Mustacchi     }
3157*55fea89dSDan Cross 
3158eef4f27bSRobert Mustacchi     combind_size = (pattern_size<<16) & 0xffff0000;
3159eef4f27bSRobert Mustacchi     combind_size |= mask_size;
3160eef4f27bSRobert Mustacchi     pattern_size &= 0xffff;
3161eef4f27bSRobert Mustacchi     mask_size &= 0xffff;
3162eef4f27bSRobert Mustacchi 
3163*55fea89dSDan Cross 
3164eef4f27bSRobert Mustacchi         //DbgBreakIf(mask_size == 0xc &&pattern_size == 0x4a);
3165*55fea89dSDan Cross 
3166eef4f27bSRobert Mustacchi 
3167eef4f27bSRobert Mustacchi     if(mask_size == 0 || mask_size > LM_NWUF_PATTERN_MASK_SIZE)
3168eef4f27bSRobert Mustacchi     {
3169eef4f27bSRobert Mustacchi         DbgBreakMsg("Invalid byte mask size\n");
3170eef4f27bSRobert Mustacchi 
3171eef4f27bSRobert Mustacchi         return LM_STATUS_FAILURE;
3172eef4f27bSRobert Mustacchi     }
3173eef4f27bSRobert Mustacchi 
3174eef4f27bSRobert Mustacchi     /* If this is a duplicate entry, we are done. */
3175eef4f27bSRobert Mustacchi     nwuf = find_nwuf(
3176*55fea89dSDan Cross             &pdev->nwuf_list,
3177*55fea89dSDan Cross             mask_size,
3178*55fea89dSDan Cross             byte_mask, pattern,
3179eef4f27bSRobert Mustacchi             max_nwuf_cnt);
3180eef4f27bSRobert Mustacchi 
3181eef4f27bSRobert Mustacchi     if(nwuf)
3182eef4f27bSRobert Mustacchi     {
3183eef4f27bSRobert Mustacchi         DbgMessage(pdev, INFORM, "Duplicated nwuf entry.\n");
3184eef4f27bSRobert Mustacchi 
3185eef4f27bSRobert Mustacchi         return LM_STATUS_EXISTING_OBJECT;
3186eef4f27bSRobert Mustacchi     }
3187eef4f27bSRobert Mustacchi 
3188eef4f27bSRobert Mustacchi     /* Find an empty slot. */
3189eef4f27bSRobert Mustacchi     nwuf = NULL;
3190eef4f27bSRobert Mustacchi     for(idx = 0; idx < max_nwuf_cnt; idx++)
3191eef4f27bSRobert Mustacchi     {
3192eef4f27bSRobert Mustacchi         if(pdev->nwuf_list.nwuf_arr[idx].size == 0)
3193eef4f27bSRobert Mustacchi         {
3194eef4f27bSRobert Mustacchi             nwuf = &pdev->nwuf_list.nwuf_arr[idx];
3195eef4f27bSRobert Mustacchi             break;
3196eef4f27bSRobert Mustacchi         }
3197eef4f27bSRobert Mustacchi     }
3198eef4f27bSRobert Mustacchi 
3199eef4f27bSRobert Mustacchi     /*
3200eef4f27bSRobert Mustacchi      * LHDBG_PRINT(("%p Adding NWUF[%d], mask size: %d, pattern size: %d\n",
3201eef4f27bSRobert Mustacchi                 pdev,idx,mask_size,pattern_size));
3202eef4f27bSRobert Mustacchi     LHDBG_PRINT(("mask array:\n"));
3203eef4f27bSRobert Mustacchi 
3204eef4f27bSRobert Mustacchi     for (i=0;i<mask_size;i++)
3205eef4f27bSRobert Mustacchi     {
3206eef4f27bSRobert Mustacchi         if (0 == i%16) LH_PRINTK(("\n"));
3207eef4f27bSRobert Mustacchi         LH_PRINTK(("%02x ", byte_mask[i]));
3208eef4f27bSRobert Mustacchi     }
3209eef4f27bSRobert Mustacchi     LH_PRINTK(("\npattern:\n"));
3210*55fea89dSDan Cross 
3211eef4f27bSRobert Mustacchi     for (i=0;i<mask_size;i++)
3212eef4f27bSRobert Mustacchi     {
3213*55fea89dSDan Cross         for (j=0;j<8;j++)
3214eef4f27bSRobert Mustacchi         {
3215eef4f27bSRobert Mustacchi             if (0 == (i*8+j)%16)
3216eef4f27bSRobert Mustacchi             {
3217eef4f27bSRobert Mustacchi                 LH_PRINTK(("\n"));
3218eef4f27bSRobert Mustacchi             }
3219eef4f27bSRobert Mustacchi             if (byte_mask[i] & 1<<j)
3220eef4f27bSRobert Mustacchi             {
3221eef4f27bSRobert Mustacchi                 LH_PRINTK(("[%02x] ",pattern[i*8+j]));
3222eef4f27bSRobert Mustacchi             }
3223eef4f27bSRobert Mustacchi             else
3224eef4f27bSRobert Mustacchi             {
3225eef4f27bSRobert Mustacchi                 if (pattern_size && i*8+j>=pattern_size)
3226eef4f27bSRobert Mustacchi                 {
3227eef4f27bSRobert Mustacchi                     LH_PRINTK(("-%02x- ",pattern[i*8+j]));
3228eef4f27bSRobert Mustacchi                 }
3229eef4f27bSRobert Mustacchi                 else
3230eef4f27bSRobert Mustacchi                 {
3231eef4f27bSRobert Mustacchi                     LH_PRINTK((" %02x  ",pattern[i*8+j]));
3232eef4f27bSRobert Mustacchi                 }
3233*55fea89dSDan Cross 
3234eef4f27bSRobert Mustacchi             }
3235eef4f27bSRobert Mustacchi         }
3236eef4f27bSRobert Mustacchi     }
3237eef4f27bSRobert Mustacchi     LH_PRINTK(("\n"));
3238eef4f27bSRobert Mustacchi */
3239eef4f27bSRobert Mustacchi 
3240eef4f27bSRobert Mustacchi     if(nwuf == NULL)
3241eef4f27bSRobert Mustacchi     {
3242eef4f27bSRobert Mustacchi         DbgMessage(pdev, WARN, "Cannot add Nwuf, exceeded maximum.\n");
3243eef4f27bSRobert Mustacchi 
3244eef4f27bSRobert Mustacchi         return LM_STATUS_RESOURCE;
3245eef4f27bSRobert Mustacchi     }
3246eef4f27bSRobert Mustacchi 
3247eef4f27bSRobert Mustacchi     pdev->nwuf_list.cnt++;
3248eef4f27bSRobert Mustacchi 
3249eef4f27bSRobert Mustacchi     /* Save nwuf data. */
3250eef4f27bSRobert Mustacchi     nwuf->size = mask_size;
3251eef4f27bSRobert Mustacchi 
3252*55fea89dSDan Cross     if (pattern_size)
3253eef4f27bSRobert Mustacchi     {
3254eef4f27bSRobert Mustacchi         nwuf->size = combind_size;
3255eef4f27bSRobert Mustacchi         goto _handle_win7_pattern;
3256eef4f27bSRobert Mustacchi     }
3257*55fea89dSDan Cross 
3258eef4f27bSRobert Mustacchi     for(j = 0; j < mask_size; j++)
3259eef4f27bSRobert Mustacchi     {
3260eef4f27bSRobert Mustacchi         nwuf->mask[j] = byte_mask[j];
3261eef4f27bSRobert Mustacchi 
3262eef4f27bSRobert Mustacchi         for(k = 0; k < 8; k++)
3263eef4f27bSRobert Mustacchi         {
3264eef4f27bSRobert Mustacchi             if(byte_mask[j] & (1 << k))
3265eef4f27bSRobert Mustacchi             {
3266eef4f27bSRobert Mustacchi                 nwuf->pattern[j*8 + k] = pattern[j*8 + k];
3267eef4f27bSRobert Mustacchi             }
3268eef4f27bSRobert Mustacchi             else
3269eef4f27bSRobert Mustacchi             {
3270eef4f27bSRobert Mustacchi                 nwuf->pattern[j*8 + k] = 0;
3271eef4f27bSRobert Mustacchi             }
3272eef4f27bSRobert Mustacchi         }
3273eef4f27bSRobert Mustacchi     }
3274eef4f27bSRobert Mustacchi 
3275eef4f27bSRobert Mustacchi     /* The byte patterns immediately following the byte that is enabled
3276eef4f27bSRobert Mustacchi      * for comparision need to be set to 0xff.  This will help facilitate
3277eef4f27bSRobert Mustacchi      * the programming of pattern onto the chip.  The end of the pattern is
3278eef4f27bSRobert Mustacchi      * indicated by the first 0xff byte that is not enabled for comparision. */
3279eef4f27bSRobert Mustacchi     if(byte_mask[mask_size-1])
3280eef4f27bSRobert Mustacchi     {
3281eef4f27bSRobert Mustacchi         k = 8;
3282eef4f27bSRobert Mustacchi         while(k)
3283eef4f27bSRobert Mustacchi         {
3284eef4f27bSRobert Mustacchi             k--;
3285eef4f27bSRobert Mustacchi             if(byte_mask[mask_size-1] & (1 << k))
3286eef4f27bSRobert Mustacchi             {
3287eef4f27bSRobert Mustacchi                 break;
3288eef4f27bSRobert Mustacchi             }
3289eef4f27bSRobert Mustacchi 
3290eef4f27bSRobert Mustacchi             nwuf->pattern[(mask_size-1)*8 + k] = 0xff;
3291eef4f27bSRobert Mustacchi         }
3292eef4f27bSRobert Mustacchi     }
3293eef4f27bSRobert Mustacchi 
3294eef4f27bSRobert Mustacchi     /* Set the rest of the pattern to 0xff. */
3295eef4f27bSRobert Mustacchi     for(j = mask_size; j < LM_NWUF_PATTERN_MASK_SIZE; j++)
3296eef4f27bSRobert Mustacchi     {
3297eef4f27bSRobert Mustacchi         nwuf->mask[j] = 0;
3298eef4f27bSRobert Mustacchi 
3299eef4f27bSRobert Mustacchi         for(k = 0; k < 8; k++)
3300eef4f27bSRobert Mustacchi         {
3301eef4f27bSRobert Mustacchi             nwuf->pattern[j*8 + k] = 0xff;
3302eef4f27bSRobert Mustacchi         }
3303eef4f27bSRobert Mustacchi     }
3304eef4f27bSRobert Mustacchi /*
3305eef4f27bSRobert Mustacchi     LHDBG_PRINT(("Dumping pattern before return\n"));
3306eef4f27bSRobert Mustacchi     for (i=0;i<128;i++)
3307eef4f27bSRobert Mustacchi     {
3308eef4f27bSRobert Mustacchi         if (i!=0 && i%16==0)
3309eef4f27bSRobert Mustacchi         {
3310eef4f27bSRobert Mustacchi             LH_PRINTK(("\n"));
3311eef4f27bSRobert Mustacchi         }
3312*55fea89dSDan Cross 
3313eef4f27bSRobert Mustacchi         LH_PRINTK(("%02x ",nwuf->pattern[i]));
3314*55fea89dSDan Cross 
3315eef4f27bSRobert Mustacchi     }
3316eef4f27bSRobert Mustacchi     LH_PRINTK(("\nEnd of add_nwuf\n"));
3317eef4f27bSRobert Mustacchi */
3318eef4f27bSRobert Mustacchi     return LM_STATUS_SUCCESS;
3319eef4f27bSRobert Mustacchi _handle_win7_pattern:
3320eef4f27bSRobert Mustacchi     /*
3321eef4f27bSRobert Mustacchi      * this is new for win7
3322eef4f27bSRobert Mustacchi      */
3323eef4f27bSRobert Mustacchi     l=0;
3324eef4f27bSRobert Mustacchi 
3325eef4f27bSRobert Mustacchi     /*for lxdiag build*/
3326eef4f27bSRobert Mustacchi #ifdef LINUX
3327eef4f27bSRobert Mustacchi 	{
3328eef4f27bSRobert Mustacchi 		u8_t idx;
3329eef4f27bSRobert Mustacchi 		for (idx=0; idx< LM_NWUF_PATTERN_MASK_SIZE; idx++)
3330eef4f27bSRobert Mustacchi 					nwuf->mask[idx] = 0;
3331eef4f27bSRobert Mustacchi 	}
3332eef4f27bSRobert Mustacchi #else
3333eef4f27bSRobert Mustacchi     memset(nwuf->mask,0,LM_NWUF_PATTERN_MASK_SIZE);
3334eef4f27bSRobert Mustacchi #endif
3335eef4f27bSRobert Mustacchi 
3336eef4f27bSRobert Mustacchi     for(j = 0; j < mask_size ; j++)
3337eef4f27bSRobert Mustacchi     {
3338eef4f27bSRobert Mustacchi         nwuf->mask[j] = byte_mask[j];
3339eef4f27bSRobert Mustacchi 
3340eef4f27bSRobert Mustacchi         for(k = 0; k < 8 ; k++)
3341eef4f27bSRobert Mustacchi         {
3342eef4f27bSRobert Mustacchi             if ( l<pattern_size )
3343eef4f27bSRobert Mustacchi             {
3344eef4f27bSRobert Mustacchi                 if(byte_mask[j] & (1 << k))
3345eef4f27bSRobert Mustacchi                 {
3346eef4f27bSRobert Mustacchi                     nwuf->pattern[j*8 + k] = pattern[j*8 + k];
3347eef4f27bSRobert Mustacchi                 }
3348eef4f27bSRobert Mustacchi                 else
3349eef4f27bSRobert Mustacchi                 {
3350eef4f27bSRobert Mustacchi                     nwuf->pattern[j*8 + k] = 0;
3351eef4f27bSRobert Mustacchi                 }
3352eef4f27bSRobert Mustacchi             }
3353eef4f27bSRobert Mustacchi             else
3354eef4f27bSRobert Mustacchi             {
3355eef4f27bSRobert Mustacchi                 nwuf->pattern[j*8 + k] = 0xff;
3356eef4f27bSRobert Mustacchi             }
3357eef4f27bSRobert Mustacchi             l++;
3358eef4f27bSRobert Mustacchi         }
3359eef4f27bSRobert Mustacchi     }
3360eef4f27bSRobert Mustacchi /*
3361eef4f27bSRobert Mustacchi     LHDBG_PRINT(("Dumping pattern before return\n"));
3362eef4f27bSRobert Mustacchi     for (i=0;i<128;i++)
3363eef4f27bSRobert Mustacchi     {
3364eef4f27bSRobert Mustacchi         if (i!=0 && i%16==0)
3365eef4f27bSRobert Mustacchi         {
3366eef4f27bSRobert Mustacchi             LH_PRINTK(("\n"));
3367eef4f27bSRobert Mustacchi         }
3368*55fea89dSDan Cross 
3369eef4f27bSRobert Mustacchi         LH_PRINTK(("%02x ",nwuf->pattern[i]));
3370*55fea89dSDan Cross 
3371eef4f27bSRobert Mustacchi     }
3372eef4f27bSRobert Mustacchi     LH_PRINTK(("\nEnd of add_nwuf\n"));
3373eef4f27bSRobert Mustacchi */
3374eef4f27bSRobert Mustacchi     return LM_STATUS_SUCCESS;
3375eef4f27bSRobert Mustacchi } /* lm_add_nwuf */
3376eef4f27bSRobert Mustacchi 
3377eef4f27bSRobert Mustacchi 
3378eef4f27bSRobert Mustacchi /*******************************************************************************
3379eef4f27bSRobert Mustacchi  * Description:
3380eef4f27bSRobert Mustacchi  *
3381eef4f27bSRobert Mustacchi  * Return:
3382eef4f27bSRobert Mustacchi  ******************************************************************************/
3383eef4f27bSRobert Mustacchi lm_status_t
lm_del_nwuf(lm_device_t * pdev,u32_t mask_size,u8_t * byte_mask,u8_t * pattern)3384eef4f27bSRobert Mustacchi lm_del_nwuf(
3385eef4f27bSRobert Mustacchi     lm_device_t *pdev,
3386eef4f27bSRobert Mustacchi     u32_t mask_size,
3387eef4f27bSRobert Mustacchi     u8_t *byte_mask,
3388eef4f27bSRobert Mustacchi     u8_t *pattern)
3389eef4f27bSRobert Mustacchi {
3390eef4f27bSRobert Mustacchi     lm_nwuf_t *nwuf;
3391eef4f27bSRobert Mustacchi     u32_t k;
3392eef4f27bSRobert Mustacchi     u32_t max_nwuf_cnt;
3393eef4f27bSRobert Mustacchi 
3394eef4f27bSRobert Mustacchi     if(CHIP_NUM(pdev) == CHIP_NUM_5709)
3395eef4f27bSRobert Mustacchi     {
3396eef4f27bSRobert Mustacchi         max_nwuf_cnt = LM_MAX_NWUF_CNT_5709;
3397eef4f27bSRobert Mustacchi     }
3398eef4f27bSRobert Mustacchi     else
3399eef4f27bSRobert Mustacchi     {
3400eef4f27bSRobert Mustacchi         max_nwuf_cnt = LM_MAX_NWUF_CNT;
3401eef4f27bSRobert Mustacchi     }
3402eef4f27bSRobert Mustacchi 
3403eef4f27bSRobert Mustacchi     mask_size &= 0xffff;
3404eef4f27bSRobert Mustacchi     if(mask_size == 0 || mask_size > LM_NWUF_PATTERN_MASK_SIZE)
3405eef4f27bSRobert Mustacchi     {
3406eef4f27bSRobert Mustacchi         DbgBreakMsg("Invalid byte mask size\n");
3407eef4f27bSRobert Mustacchi 
3408eef4f27bSRobert Mustacchi         return LM_STATUS_FAILURE;
3409eef4f27bSRobert Mustacchi     }
3410eef4f27bSRobert Mustacchi 
3411eef4f27bSRobert Mustacchi     /* Look for a matching pattern. */
3412eef4f27bSRobert Mustacchi     nwuf = find_nwuf(
3413*55fea89dSDan Cross             &pdev->nwuf_list,
3414*55fea89dSDan Cross             mask_size,
3415*55fea89dSDan Cross             byte_mask,
3416eef4f27bSRobert Mustacchi             pattern,
3417eef4f27bSRobert Mustacchi             max_nwuf_cnt);
3418eef4f27bSRobert Mustacchi 
3419eef4f27bSRobert Mustacchi     if(nwuf == NULL)
3420eef4f27bSRobert Mustacchi     {
3421eef4f27bSRobert Mustacchi         return LM_STATUS_OBJECT_NOT_FOUND;
3422eef4f27bSRobert Mustacchi     }
3423eef4f27bSRobert Mustacchi 
3424eef4f27bSRobert Mustacchi     nwuf->size = 0;
3425eef4f27bSRobert Mustacchi 
3426eef4f27bSRobert Mustacchi     for(k = 0; k < LM_NWUF_PATTERN_MASK_SIZE; k++)
3427eef4f27bSRobert Mustacchi     {
3428eef4f27bSRobert Mustacchi         nwuf->mask[k] = 0;
3429eef4f27bSRobert Mustacchi     }
3430eef4f27bSRobert Mustacchi 
3431eef4f27bSRobert Mustacchi     for(k = 0; k < LM_NWUF_PATTERN_SIZE; k++)
3432eef4f27bSRobert Mustacchi     {
3433eef4f27bSRobert Mustacchi         nwuf->pattern[k] = 0xff;
3434eef4f27bSRobert Mustacchi     }
3435eef4f27bSRobert Mustacchi 
3436eef4f27bSRobert Mustacchi     pdev->nwuf_list.cnt--;
3437eef4f27bSRobert Mustacchi 
3438eef4f27bSRobert Mustacchi     return LM_STATUS_SUCCESS;
3439eef4f27bSRobert Mustacchi } /* lm_del_nwuf */
3440eef4f27bSRobert Mustacchi 
3441eef4f27bSRobert Mustacchi 
3442eef4f27bSRobert Mustacchi 
3443eef4f27bSRobert Mustacchi /*******************************************************************************
3444eef4f27bSRobert Mustacchi  * Description:
3445eef4f27bSRobert Mustacchi  *
3446eef4f27bSRobert Mustacchi  * Return:
3447eef4f27bSRobert Mustacchi  ******************************************************************************/
3448eef4f27bSRobert Mustacchi void
lm_clear_nwuf(lm_device_t * pdev)3449eef4f27bSRobert Mustacchi lm_clear_nwuf(
3450eef4f27bSRobert Mustacchi     lm_device_t *pdev)
3451eef4f27bSRobert Mustacchi {
3452eef4f27bSRobert Mustacchi     u32_t j;
3453eef4f27bSRobert Mustacchi     u32_t k;
3454eef4f27bSRobert Mustacchi     u32_t max_nwuf_cnt;
3455eef4f27bSRobert Mustacchi 
3456eef4f27bSRobert Mustacchi     if(CHIP_NUM(pdev) == CHIP_NUM_5709)
3457eef4f27bSRobert Mustacchi     {
3458eef4f27bSRobert Mustacchi         max_nwuf_cnt = LM_MAX_NWUF_CNT_5709;
3459eef4f27bSRobert Mustacchi     }
3460eef4f27bSRobert Mustacchi     else
3461eef4f27bSRobert Mustacchi     {
3462eef4f27bSRobert Mustacchi         max_nwuf_cnt = LM_MAX_NWUF_CNT;
3463eef4f27bSRobert Mustacchi     }
3464*55fea89dSDan Cross 
3465eef4f27bSRobert Mustacchi     for(j = 0; j < max_nwuf_cnt; j++)
3466eef4f27bSRobert Mustacchi     {
3467eef4f27bSRobert Mustacchi         pdev->nwuf_list.nwuf_arr[j].size = 0;
3468eef4f27bSRobert Mustacchi 
3469eef4f27bSRobert Mustacchi         for(k = 0; k < LM_NWUF_PATTERN_MASK_SIZE; k++)
3470eef4f27bSRobert Mustacchi         {
3471eef4f27bSRobert Mustacchi             pdev->nwuf_list.nwuf_arr[j].mask[k] = 0;
3472eef4f27bSRobert Mustacchi         }
3473eef4f27bSRobert Mustacchi 
3474eef4f27bSRobert Mustacchi         for(k = 0; k < LM_NWUF_PATTERN_SIZE; k++)
3475eef4f27bSRobert Mustacchi         {
3476eef4f27bSRobert Mustacchi             pdev->nwuf_list.nwuf_arr[j].pattern[k] = 0xff;
3477eef4f27bSRobert Mustacchi         }
3478eef4f27bSRobert Mustacchi     }
3479eef4f27bSRobert Mustacchi 
3480eef4f27bSRobert Mustacchi     pdev->nwuf_list.cnt = 0;
3481eef4f27bSRobert Mustacchi } /* lm_clear_nwuf */
3482eef4f27bSRobert Mustacchi 
3483eef4f27bSRobert Mustacchi 
3484eef4f27bSRobert Mustacchi 
3485eef4f27bSRobert Mustacchi /*******************************************************************************
3486eef4f27bSRobert Mustacchi  * Description:
3487eef4f27bSRobert Mustacchi  *
3488eef4f27bSRobert Mustacchi  * Return:
3489eef4f27bSRobert Mustacchi  ******************************************************************************/
3490eef4f27bSRobert Mustacchi STATIC u32_t
init_nwuf_5709(lm_device_t * pdev,lm_nwuf_list_t * nwuf_list)3491eef4f27bSRobert Mustacchi init_nwuf_5709(
3492eef4f27bSRobert Mustacchi     lm_device_t *pdev,
3493eef4f27bSRobert Mustacchi     lm_nwuf_list_t *nwuf_list)
3494eef4f27bSRobert Mustacchi {
3495eef4f27bSRobert Mustacchi     lm_nwuf_t *nwuf;
3496eef4f27bSRobert Mustacchi     u16_t prev_val;
3497eef4f27bSRobert Mustacchi     u32_t nwuf_len;
3498eef4f27bSRobert Mustacchi     u32_t nwuf_cnt;
3499eef4f27bSRobert Mustacchi     u32_t offset;
3500eef4f27bSRobert Mustacchi     u8_t mask;
3501eef4f27bSRobert Mustacchi     u32_t val;
3502eef4f27bSRobert Mustacchi     u32_t idx;
3503eef4f27bSRobert Mustacchi     u8_t bit;
3504eef4f27bSRobert Mustacchi     u16_t pattern_size;
3505eef4f27bSRobert Mustacchi     u32_t nwuf_size[LM_MAX_NWUF_CNT_5709];
3506eef4f27bSRobert Mustacchi 
3507eef4f27bSRobert Mustacchi     DbgBreakIf(CHIP_NUM(pdev) != CHIP_NUM_5709);
3508eef4f27bSRobert Mustacchi     DbgBreakIf(LM_NWUF_PATTERN_SIZE > 128);
3509eef4f27bSRobert Mustacchi     DbgBreakIf(LM_MAX_NWUF_CNT_5709 > 8);
3510eef4f27bSRobert Mustacchi 
3511eef4f27bSRobert Mustacchi     REG_WR(pdev, rpm.rpm_acpi_byte_enable_ctrl, RPM_ACPI_BYTE_ENABLE_CTRL_INIT);
3512eef4f27bSRobert Mustacchi 
3513eef4f27bSRobert Mustacchi     for(idx = 0; idx < LM_MAX_NWUF_CNT_5709; idx++)
3514eef4f27bSRobert Mustacchi     {
3515eef4f27bSRobert Mustacchi         nwuf = &nwuf_list->nwuf_arr[idx];
3516eef4f27bSRobert Mustacchi         nwuf_size[idx] = nwuf->size;
3517eef4f27bSRobert Mustacchi     }
3518eef4f27bSRobert Mustacchi     for(idx = 0; idx < 1000; idx++)
3519eef4f27bSRobert Mustacchi     {
3520eef4f27bSRobert Mustacchi         mm_wait(pdev, 5);
3521eef4f27bSRobert Mustacchi 
3522eef4f27bSRobert Mustacchi         REG_RD(pdev, rpm.rpm_acpi_byte_enable_ctrl, &val);
3523eef4f27bSRobert Mustacchi         if((val & RPM_ACPI_BYTE_ENABLE_CTRL_INIT) == 0)
3524eef4f27bSRobert Mustacchi         {
3525eef4f27bSRobert Mustacchi             break;
3526eef4f27bSRobert Mustacchi         }
3527eef4f27bSRobert Mustacchi     }
3528eef4f27bSRobert Mustacchi     DbgBreakIf(val & RPM_ACPI_BYTE_ENABLE_CTRL_INIT);
3529eef4f27bSRobert Mustacchi 
3530eef4f27bSRobert Mustacchi     val = 0;
3531eef4f27bSRobert Mustacchi     for(idx = 0; idx < 4; idx++)
3532eef4f27bSRobert Mustacchi     {
3533eef4f27bSRobert Mustacchi         nwuf = &nwuf_list->nwuf_arr[idx];
3534eef4f27bSRobert Mustacchi         pattern_size = nwuf->size >>16;
3535eef4f27bSRobert Mustacchi         nwuf->size &= 0xffff;
3536eef4f27bSRobert Mustacchi 
3537eef4f27bSRobert Mustacchi         DbgBreakIf(nwuf->size > LM_NWUF_PATTERN_MASK_SIZE);
3538eef4f27bSRobert Mustacchi 
3539eef4f27bSRobert Mustacchi         if(nwuf->size == 0)
3540eef4f27bSRobert Mustacchi         {
3541eef4f27bSRobert Mustacchi             continue;
3542eef4f27bSRobert Mustacchi         }
3543eef4f27bSRobert Mustacchi         if (pattern_size)
3544eef4f27bSRobert Mustacchi         {
3545eef4f27bSRobert Mustacchi             val |= (pattern_size) << ((3 - idx) * 8);
3546eef4f27bSRobert Mustacchi         }
3547eef4f27bSRobert Mustacchi         else
3548eef4f27bSRobert Mustacchi         {
3549eef4f27bSRobert Mustacchi             val |= (nwuf->size * 8) << ((3 - idx) * 8);
3550eef4f27bSRobert Mustacchi         }
3551eef4f27bSRobert Mustacchi     }
3552eef4f27bSRobert Mustacchi     REG_WR(pdev, rpm.rpm_acpi_pattern_len0, val);
3553eef4f27bSRobert Mustacchi 
3554eef4f27bSRobert Mustacchi     val = 0;
3555eef4f27bSRobert Mustacchi     for(idx = 4; idx < LM_MAX_NWUF_CNT_5709; idx++)
3556eef4f27bSRobert Mustacchi     {
3557eef4f27bSRobert Mustacchi         nwuf = &nwuf_list->nwuf_arr[idx];
3558eef4f27bSRobert Mustacchi         pattern_size = nwuf->size >>16;
3559eef4f27bSRobert Mustacchi         nwuf->size &= 0xffff;
3560eef4f27bSRobert Mustacchi 
3561eef4f27bSRobert Mustacchi         DbgBreakIf(nwuf->size > LM_NWUF_PATTERN_MASK_SIZE);
3562eef4f27bSRobert Mustacchi 
3563eef4f27bSRobert Mustacchi         if(nwuf->size == 0)
3564eef4f27bSRobert Mustacchi         {
3565eef4f27bSRobert Mustacchi             continue;
3566eef4f27bSRobert Mustacchi         }
3567eef4f27bSRobert Mustacchi 
3568eef4f27bSRobert Mustacchi         if (pattern_size)
3569eef4f27bSRobert Mustacchi         {
3570eef4f27bSRobert Mustacchi             val |= (pattern_size) << ((7 - idx) * 8);
3571eef4f27bSRobert Mustacchi         }
3572eef4f27bSRobert Mustacchi         else
3573eef4f27bSRobert Mustacchi         {
3574eef4f27bSRobert Mustacchi             val |= (nwuf->size * 8) << ((7 - idx) * 8);
3575eef4f27bSRobert Mustacchi         }
3576eef4f27bSRobert Mustacchi 
3577eef4f27bSRobert Mustacchi         // old code val |= (nwuf->size * 8) << ((7 - idx) * 8);
3578eef4f27bSRobert Mustacchi     }
3579eef4f27bSRobert Mustacchi     REG_WR(pdev, rpm.rpm_acpi_pattern_len1, val);
3580eef4f27bSRobert Mustacchi 
3581eef4f27bSRobert Mustacchi     for(offset = 0; offset < LM_NWUF_PATTERN_SIZE; offset++)
3582eef4f27bSRobert Mustacchi     {
3583eef4f27bSRobert Mustacchi         val = 0;
3584eef4f27bSRobert Mustacchi 
3585eef4f27bSRobert Mustacchi         for(idx = 0; idx < LM_MAX_NWUF_CNT_5709; idx++)
3586eef4f27bSRobert Mustacchi         {
3587eef4f27bSRobert Mustacchi             nwuf = &nwuf_list->nwuf_arr[idx];
3588eef4f27bSRobert Mustacchi             pattern_size = nwuf_size[idx]>>16;
3589*55fea89dSDan Cross 
3590eef4f27bSRobert Mustacchi             if(nwuf->size == 0 || offset > nwuf->size * 8)
3591eef4f27bSRobert Mustacchi             {
3592eef4f27bSRobert Mustacchi                 continue;
3593eef4f27bSRobert Mustacchi             }
3594eef4f27bSRobert Mustacchi 
3595eef4f27bSRobert Mustacchi             mask = nwuf->mask[offset/8];
3596eef4f27bSRobert Mustacchi             bit = offset % 8;
3597eef4f27bSRobert Mustacchi 
3598eef4f27bSRobert Mustacchi             if(mask & (1 << bit))
3599eef4f27bSRobert Mustacchi             {
3600eef4f27bSRobert Mustacchi                 val |= 1 << idx;
3601eef4f27bSRobert Mustacchi             }
3602eef4f27bSRobert Mustacchi         }
3603eef4f27bSRobert Mustacchi 
3604eef4f27bSRobert Mustacchi         REG_WR(pdev, rpm.rpm_acpi_data, val);
3605eef4f27bSRobert Mustacchi 
3606eef4f27bSRobert Mustacchi         /* Perform the Write to the byte enable memory, The actual pattern
3607eef4f27bSRobert Mustacchi          * byte enables start from byte address 2. the first two bytes of
3608eef4f27bSRobert Mustacchi          * a packet are always 0 and inserted by EMAC to align the IP header
3609eef4f27bSRobert Mustacchi          * to 4-byte boudary. */
3610eef4f27bSRobert Mustacchi         REG_WR(
3611eef4f27bSRobert Mustacchi             pdev,
3612eef4f27bSRobert Mustacchi             rpm.rpm_acpi_byte_enable_ctrl,
3613eef4f27bSRobert Mustacchi             RPM_ACPI_BYTE_ENABLE_CTRL_WR | offset);
3614eef4f27bSRobert Mustacchi         REG_RD(pdev, rpm.rpm_acpi_byte_enable_ctrl, &val);
3615eef4f27bSRobert Mustacchi         DbgBreakIf(val & RPM_ACPI_BYTE_ENABLE_CTRL_WR);
3616eef4f27bSRobert Mustacchi     }
3617eef4f27bSRobert Mustacchi 
3618eef4f27bSRobert Mustacchi     nwuf_cnt = 0;
3619eef4f27bSRobert Mustacchi 
3620eef4f27bSRobert Mustacchi     for(idx = 0; idx < LM_MAX_NWUF_CNT_5709; idx++)
3621eef4f27bSRobert Mustacchi     {
3622eef4f27bSRobert Mustacchi         REG_WR(
3623eef4f27bSRobert Mustacchi             pdev,
3624eef4f27bSRobert Mustacchi             rpm.rpm_acpi_pattern_ctrl,
3625eef4f27bSRobert Mustacchi             RPM_ACPI_PATTERN_CTRL_CRC_SM_CLR|idx);
3626eef4f27bSRobert Mustacchi         REG_RD(pdev, rpm.rpm_acpi_pattern_ctrl, &val);
3627eef4f27bSRobert Mustacchi         DbgBreakIf(val & RPM_ACPI_PATTERN_CTRL_CRC_SM_CLR);
3628eef4f27bSRobert Mustacchi 
3629eef4f27bSRobert Mustacchi         nwuf = &nwuf_list->nwuf_arr[idx];
3630eef4f27bSRobert Mustacchi         if(nwuf->size == 0)
3631eef4f27bSRobert Mustacchi         {
3632eef4f27bSRobert Mustacchi             continue;
3633eef4f27bSRobert Mustacchi         }
3634eef4f27bSRobert Mustacchi         pattern_size = nwuf_size[idx]>>16;
3635eef4f27bSRobert Mustacchi 
3636eef4f27bSRobert Mustacchi         /* The CRC calculation is done on 64-bit data. So the length of the
3637eef4f27bSRobert Mustacchi          * pattern over which CRC needs to be calculated needs to be padded
3638eef4f27bSRobert Mustacchi          * by 0 to 7 bytes to make it 8 byte aligned. */
3639eef4f27bSRobert Mustacchi 
3640eef4f27bSRobert Mustacchi         if (pattern_size)
3641eef4f27bSRobert Mustacchi         {
3642eef4f27bSRobert Mustacchi             nwuf_len = pattern_size;
3643eef4f27bSRobert Mustacchi         }
3644eef4f27bSRobert Mustacchi         else
3645eef4f27bSRobert Mustacchi         {
3646eef4f27bSRobert Mustacchi             nwuf_len = (nwuf->size * 8);
3647eef4f27bSRobert Mustacchi         }
3648eef4f27bSRobert Mustacchi         nwuf_len += 2;  /* 2-byte padding. */
3649eef4f27bSRobert Mustacchi         nwuf_len = (nwuf_len + 3) & ~3;
3650eef4f27bSRobert Mustacchi 
3651eef4f27bSRobert Mustacchi         prev_val = 0;
3652eef4f27bSRobert Mustacchi 
3653eef4f27bSRobert Mustacchi         for(offset = 0; offset < nwuf_len; offset += 4)
3654eef4f27bSRobert Mustacchi         {
3655eef4f27bSRobert Mustacchi             val = 0;
3656eef4f27bSRobert Mustacchi 
3657eef4f27bSRobert Mustacchi             for(bit = 0; bit < 4; bit++)
3658eef4f27bSRobert Mustacchi             {
3659eef4f27bSRobert Mustacchi                 if (pattern_size)
3660eef4f27bSRobert Mustacchi                 {
3661eef4f27bSRobert Mustacchi                     if(offset < pattern_size)
3662eef4f27bSRobert Mustacchi                     {
3663eef4f27bSRobert Mustacchi                         mask = nwuf->mask[offset/8];
3664eef4f27bSRobert Mustacchi                     }
3665eef4f27bSRobert Mustacchi                     else
3666eef4f27bSRobert Mustacchi                     {
3667eef4f27bSRobert Mustacchi                         mask = 0;
3668eef4f27bSRobert Mustacchi                     }
3669eef4f27bSRobert Mustacchi                 }
3670eef4f27bSRobert Mustacchi                 else
3671eef4f27bSRobert Mustacchi                 {
3672eef4f27bSRobert Mustacchi                     if(offset < nwuf->size * 8)
3673eef4f27bSRobert Mustacchi                     {
3674eef4f27bSRobert Mustacchi                         mask = nwuf->mask[offset/8];
3675eef4f27bSRobert Mustacchi                     }
3676eef4f27bSRobert Mustacchi                     else
3677eef4f27bSRobert Mustacchi                     {
3678eef4f27bSRobert Mustacchi                         mask = 0;
3679eef4f27bSRobert Mustacchi                     }
3680eef4f27bSRobert Mustacchi                 }
3681eef4f27bSRobert Mustacchi                 if(mask & (1 << (bit + (offset % 8))))
3682eef4f27bSRobert Mustacchi                 {
3683eef4f27bSRobert Mustacchi                     val |= nwuf->pattern[offset+bit] << ((3 - bit) * 8);
3684eef4f27bSRobert Mustacchi                 }
3685eef4f27bSRobert Mustacchi             }
3686eef4f27bSRobert Mustacchi 
3687eef4f27bSRobert Mustacchi             REG_WR(pdev, rpm.rpm_acpi_data, (prev_val << 16) | (val >> 16));
3688eef4f27bSRobert Mustacchi             prev_val = (u16_t) val;
3689eef4f27bSRobert Mustacchi 
3690eef4f27bSRobert Mustacchi             REG_WR(
3691eef4f27bSRobert Mustacchi                 pdev,
3692eef4f27bSRobert Mustacchi                 rpm.rpm_acpi_pattern_ctrl,
3693eef4f27bSRobert Mustacchi                 RPM_ACPI_PATTERN_CTRL_WR | idx);
3694eef4f27bSRobert Mustacchi             REG_RD(pdev, rpm.rpm_acpi_pattern_ctrl, &val);
3695eef4f27bSRobert Mustacchi             DbgBreakIf(val & RPM_ACPI_PATTERN_CTRL_WR);
3696eef4f27bSRobert Mustacchi         }
3697eef4f27bSRobert Mustacchi 
3698eef4f27bSRobert Mustacchi         nwuf_cnt++;
3699eef4f27bSRobert Mustacchi     }
3700eef4f27bSRobert Mustacchi     for(idx = 0; idx < LM_MAX_NWUF_CNT_5709; idx++)
3701eef4f27bSRobert Mustacchi     {
3702eef4f27bSRobert Mustacchi         nwuf = &nwuf_list->nwuf_arr[idx];
3703eef4f27bSRobert Mustacchi         nwuf->size = nwuf_size[idx];
3704eef4f27bSRobert Mustacchi     }
3705eef4f27bSRobert Mustacchi 
3706eef4f27bSRobert Mustacchi     return nwuf_cnt;
3707eef4f27bSRobert Mustacchi } /* init_nwuf_5709 */
3708eef4f27bSRobert Mustacchi 
3709eef4f27bSRobert Mustacchi 
3710eef4f27bSRobert Mustacchi 
3711eef4f27bSRobert Mustacchi /*******************************************************************************
3712eef4f27bSRobert Mustacchi  * Description:
3713eef4f27bSRobert Mustacchi  *
3714eef4f27bSRobert Mustacchi  * Return:
3715eef4f27bSRobert Mustacchi  ******************************************************************************/
3716eef4f27bSRobert Mustacchi STATIC u32_t
init_nwuf_5706(lm_device_t * pdev,lm_nwuf_list_t * nwuf_list)3717eef4f27bSRobert Mustacchi init_nwuf_5706(
3718eef4f27bSRobert Mustacchi     lm_device_t *pdev,
3719eef4f27bSRobert Mustacchi     lm_nwuf_list_t *nwuf_list)
3720eef4f27bSRobert Mustacchi {
3721eef4f27bSRobert Mustacchi     typedef union _acpi_wol_pat_t
3722eef4f27bSRobert Mustacchi     {
3723eef4f27bSRobert Mustacchi         #if defined(LITTLE_ENDIAN)
3724eef4f27bSRobert Mustacchi         struct _acpi_wol_pat_as_u8_t
3725eef4f27bSRobert Mustacchi         {
3726eef4f27bSRobert Mustacchi             u8_t pat[7];
3727eef4f27bSRobert Mustacchi             u8_t ena;
3728eef4f27bSRobert Mustacchi         } as_u8;
3729eef4f27bSRobert Mustacchi 
3730eef4f27bSRobert Mustacchi         struct _acpi_wol_pat_as_u32_t
3731eef4f27bSRobert Mustacchi         {
3732eef4f27bSRobert Mustacchi             u32_t low;
3733eef4f27bSRobert Mustacchi             u32_t high;
3734eef4f27bSRobert Mustacchi         } as_u32;
3735eef4f27bSRobert Mustacchi         #elif defined(BIG_ENDIAN)
3736eef4f27bSRobert Mustacchi         struct _acpi_wol_pat_as_u8_t
3737eef4f27bSRobert Mustacchi         {
3738eef4f27bSRobert Mustacchi             u8_t ena;
3739eef4f27bSRobert Mustacchi             u8_t pat[7];
3740eef4f27bSRobert Mustacchi         } as_u8;
3741eef4f27bSRobert Mustacchi 
3742eef4f27bSRobert Mustacchi         struct _acpi_wol_pat_as_u32_t
3743eef4f27bSRobert Mustacchi         {
3744eef4f27bSRobert Mustacchi             u32_t high;
3745eef4f27bSRobert Mustacchi             u32_t low;
3746eef4f27bSRobert Mustacchi         } as_u32;
3747eef4f27bSRobert Mustacchi         #endif
3748eef4f27bSRobert Mustacchi     } acpi_wol_pat_t;
3749eef4f27bSRobert Mustacchi 
3750eef4f27bSRobert Mustacchi     u32_t filler_pattern_idx;
3751eef4f27bSRobert Mustacchi     acpi_wol_pat_t wol_pat;
3752eef4f27bSRobert Mustacchi     u32_t pattern_cnt;
3753eef4f27bSRobert Mustacchi     u8_t val;
3754eef4f27bSRobert Mustacchi     u32_t j;
3755eef4f27bSRobert Mustacchi     u32_t k;
3756eef4f27bSRobert Mustacchi     u8_t idx;
3757eef4f27bSRobert Mustacchi     u32_t nwuf_size[LM_MAX_NWUF_CNT];
3758eef4f27bSRobert Mustacchi     lm_nwuf_t *nwuf;
3759*55fea89dSDan Cross 
3760eef4f27bSRobert Mustacchi     /*
3761eef4f27bSRobert Mustacchi      * 06/08 doesn't seem to have pattern size like those of 09
3762eef4f27bSRobert Mustacchi      */
3763eef4f27bSRobert Mustacchi     for(idx = 0; idx < LM_MAX_NWUF_CNT; idx++)
3764eef4f27bSRobert Mustacchi     {
3765eef4f27bSRobert Mustacchi         nwuf = &nwuf_list->nwuf_arr[idx];
3766eef4f27bSRobert Mustacchi         nwuf_size[idx] = nwuf->size;
3767eef4f27bSRobert Mustacchi         nwuf->size &= 0xffff;
3768eef4f27bSRobert Mustacchi     }
3769eef4f27bSRobert Mustacchi 
3770eef4f27bSRobert Mustacchi     DbgBreakIf(LM_NWUF_PATTERN_SIZE > 128);
3771eef4f27bSRobert Mustacchi     DbgBreakIf(LM_MAX_NWUF_CNT > 7);
3772eef4f27bSRobert Mustacchi     DbgBreakIf(CHIP_NUM(pdev) != CHIP_NUM_5706 &&
3773eef4f27bSRobert Mustacchi                CHIP_NUM(pdev) != CHIP_NUM_5708);
3774eef4f27bSRobert Mustacchi 
3775eef4f27bSRobert Mustacchi     /* If a pattern is not present, we will fill the pattern buffer
3776eef4f27bSRobert Mustacchi      * with the pattern with this index.  The pattern buffer cannot
3777eef4f27bSRobert Mustacchi      * have an empty pattern otherwise we will get a false detection. */
3778eef4f27bSRobert Mustacchi     filler_pattern_idx = 0;
3779eef4f27bSRobert Mustacchi 
3780eef4f27bSRobert Mustacchi     /* Find out the number of patterns. */
3781eef4f27bSRobert Mustacchi     pattern_cnt = 0;
3782eef4f27bSRobert Mustacchi     for(k = 0; k < LM_MAX_NWUF_CNT; k++)
3783eef4f27bSRobert Mustacchi     {
3784eef4f27bSRobert Mustacchi         if(nwuf_list->nwuf_arr[k].size)
3785eef4f27bSRobert Mustacchi         {
3786eef4f27bSRobert Mustacchi             pattern_cnt++;
3787eef4f27bSRobert Mustacchi             filler_pattern_idx = k;
3788eef4f27bSRobert Mustacchi         }
3789eef4f27bSRobert Mustacchi     }
3790eef4f27bSRobert Mustacchi 
3791eef4f27bSRobert Mustacchi     /* Program the pattern. */
3792eef4f27bSRobert Mustacchi     for(j = 0; j < LM_NWUF_PATTERN_SIZE; j++)
3793eef4f27bSRobert Mustacchi     {
3794eef4f27bSRobert Mustacchi         wol_pat.as_u32.low = 0x0;
3795eef4f27bSRobert Mustacchi         wol_pat.as_u32.high = 0x0;
3796eef4f27bSRobert Mustacchi 
3797eef4f27bSRobert Mustacchi         /* Build the enable bits. */
3798eef4f27bSRobert Mustacchi         wol_pat.as_u8.ena = 0;
3799eef4f27bSRobert Mustacchi         for(k = 0; k < LM_MAX_NWUF_CNT; k++)
3800eef4f27bSRobert Mustacchi         {
3801eef4f27bSRobert Mustacchi             if(nwuf_list->nwuf_arr[k].size == 0)
3802eef4f27bSRobert Mustacchi             {
3803eef4f27bSRobert Mustacchi                 val = nwuf_list->nwuf_arr[filler_pattern_idx].mask[j/8];
3804eef4f27bSRobert Mustacchi             }
3805eef4f27bSRobert Mustacchi             else if((j/8) >= nwuf_list->nwuf_arr[k].size)
3806eef4f27bSRobert Mustacchi             {
3807eef4f27bSRobert Mustacchi                 val = 0;
3808eef4f27bSRobert Mustacchi             }
3809eef4f27bSRobert Mustacchi             else
3810eef4f27bSRobert Mustacchi             {
3811eef4f27bSRobert Mustacchi                 val = nwuf_list->nwuf_arr[k].mask[j/8];
3812eef4f27bSRobert Mustacchi             }
3813eef4f27bSRobert Mustacchi 
3814eef4f27bSRobert Mustacchi             /* Determine if a byte is enabled for comparision. */
3815eef4f27bSRobert Mustacchi             if(val & (1 << (j % 8)))
3816eef4f27bSRobert Mustacchi             {
3817eef4f27bSRobert Mustacchi                 wol_pat.as_u8.ena |= 1 << k;
3818eef4f27bSRobert Mustacchi             }
3819eef4f27bSRobert Mustacchi         }
3820eef4f27bSRobert Mustacchi 
3821eef4f27bSRobert Mustacchi         DbgMessage1(pdev, VERBOSE, "%02x: ", j);
3822eef4f27bSRobert Mustacchi 
3823eef4f27bSRobert Mustacchi         /* Enter the byte of each pattern that will be used for comparison. */
3824eef4f27bSRobert Mustacchi         for(k = 0; k < LM_MAX_NWUF_CNT; k++)
3825eef4f27bSRobert Mustacchi         {
3826eef4f27bSRobert Mustacchi             /* Check to see if we are at the end of the pattern.  0xff
3827eef4f27bSRobert Mustacchi              * will terminate the pattern.  If there is no pattern present
3828eef4f27bSRobert Mustacchi              * we cannot terminate with 0xff. */
3829eef4f27bSRobert Mustacchi             if(nwuf_list->nwuf_arr[k].size == 0)
3830eef4f27bSRobert Mustacchi             {
3831eef4f27bSRobert Mustacchi                 val = nwuf_list->nwuf_arr[filler_pattern_idx].pattern[j];
3832eef4f27bSRobert Mustacchi                 DbgMessage(pdev, VERBOSE, "xx ");
3833eef4f27bSRobert Mustacchi             }
3834eef4f27bSRobert Mustacchi             else if((j/8) >= nwuf_list->nwuf_arr[k].size)
3835eef4f27bSRobert Mustacchi             {
3836eef4f27bSRobert Mustacchi                 val = 0xff;
3837eef4f27bSRobert Mustacchi                 DbgMessage(pdev, VERBOSE, "ff ");
3838eef4f27bSRobert Mustacchi             }
3839eef4f27bSRobert Mustacchi             else
3840eef4f27bSRobert Mustacchi             {
3841eef4f27bSRobert Mustacchi                 val = nwuf_list->nwuf_arr[k].pattern[j];
3842eef4f27bSRobert Mustacchi                 DbgMessage1(pdev, VERBOSE, "%02x ", val);
3843eef4f27bSRobert Mustacchi             }
3844eef4f27bSRobert Mustacchi 
3845eef4f27bSRobert Mustacchi             /* Format of the ACPI_WOL pattern from low address to high on a
3846eef4f27bSRobert Mustacchi              * little endian system:
3847eef4f27bSRobert Mustacchi              *    pat0_6 pat0_5 pat0_4 pat0_3 pat0_2 pat0_1 pat0_0 ena0
3848eef4f27bSRobert Mustacchi              *
3849eef4f27bSRobert Mustacchi              * on a big endian system:
3850eef4f27bSRobert Mustacchi              *    ena0 pat0_0 pat0_1 pat0_2 pat0_3 pat0_4 pat0_5 pat0_6 */
3851eef4f27bSRobert Mustacchi             #if defined(LITTLE_ENDIAN)
3852eef4f27bSRobert Mustacchi             wol_pat.as_u8.pat[6-k] = val;
3853eef4f27bSRobert Mustacchi             #elif defined(BIG_ENDIAN)
3854eef4f27bSRobert Mustacchi             wol_pat.as_u8.pat[k] = val;
3855eef4f27bSRobert Mustacchi             #endif
3856eef4f27bSRobert Mustacchi         }
3857eef4f27bSRobert Mustacchi 
3858eef4f27bSRobert Mustacchi         DbgMessage2(pdev, VERBOSE, "   %08x %08x\n",
3859eef4f27bSRobert Mustacchi             wol_pat.as_u32.high, wol_pat.as_u32.low);
3860eef4f27bSRobert Mustacchi 
3861eef4f27bSRobert Mustacchi         /* Swap the even 64-bit word with the odd 64-bit word.  This is
3862eef4f27bSRobert Mustacchi          * they way it works.  Don't ask why.  So the values written
3863eef4f27bSRobert Mustacchi          * to the header buffer looks as follows:
3864eef4f27bSRobert Mustacchi          *    0x0000:  ena1   pat1_0 pat1_1 pat1_2
3865eef4f27bSRobert Mustacchi          *    0x0004:  pat1_3 pat1_4 pat1_5 pat1_6
3866eef4f27bSRobert Mustacchi          *    0x0008:  ena0   pat0_0 pat0_1 pat0_2
3867eef4f27bSRobert Mustacchi          *    0x000c:  pat0_3 pat0_4 pat0_5 pat0_6
3868eef4f27bSRobert Mustacchi          *    0x0010:  ena3   pat3_0 pat3_1 pat3_2
3869eef4f27bSRobert Mustacchi          *    0x0014:  pat3_3 pat3_4 pat3_5 pat3_6
3870eef4f27bSRobert Mustacchi          *    0x0018:  ena2   pat2_0 pat2_1 pat2_2
3871eef4f27bSRobert Mustacchi          *    0x001c:  pat2_3 pat2_4 pat2_5 pat2_6 */
3872eef4f27bSRobert Mustacchi         if(j % 2)
3873eef4f27bSRobert Mustacchi         {
3874eef4f27bSRobert Mustacchi             REG_WR_IND(
3875eef4f27bSRobert Mustacchi                 pdev,
3876eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, tas.tas_thbuf[(j-1) * 2]),
3877eef4f27bSRobert Mustacchi                 wol_pat.as_u32.high);
3878eef4f27bSRobert Mustacchi             REG_WR_IND(
3879eef4f27bSRobert Mustacchi                 pdev,
3880eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, tas.tas_thbuf[(j-1) * 2 + 1]),
3881eef4f27bSRobert Mustacchi                 wol_pat.as_u32.low);
3882eef4f27bSRobert Mustacchi         }
3883eef4f27bSRobert Mustacchi         else
3884eef4f27bSRobert Mustacchi         {
3885eef4f27bSRobert Mustacchi             REG_WR_IND(
3886eef4f27bSRobert Mustacchi                 pdev,
3887eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, tas.tas_thbuf[(j+1) * 2]),
3888eef4f27bSRobert Mustacchi                 wol_pat.as_u32.high);
3889eef4f27bSRobert Mustacchi             REG_WR_IND(
3890eef4f27bSRobert Mustacchi                 pdev,
3891eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, tas.tas_thbuf[(j+1) * 2 + 1]),
3892eef4f27bSRobert Mustacchi                 wol_pat.as_u32.low);
3893eef4f27bSRobert Mustacchi         }
3894eef4f27bSRobert Mustacchi     }
3895eef4f27bSRobert Mustacchi 
3896eef4f27bSRobert Mustacchi     for(idx = 0; idx < LM_MAX_NWUF_CNT; idx++)
3897eef4f27bSRobert Mustacchi     {
3898eef4f27bSRobert Mustacchi         nwuf = &nwuf_list->nwuf_arr[idx];
3899eef4f27bSRobert Mustacchi         nwuf->size = nwuf_size[idx];
3900eef4f27bSRobert Mustacchi     }
3901eef4f27bSRobert Mustacchi 
3902eef4f27bSRobert Mustacchi     return pattern_cnt;
3903eef4f27bSRobert Mustacchi } /* init_nwuf_5706 */
3904eef4f27bSRobert Mustacchi 
3905eef4f27bSRobert Mustacchi 
3906eef4f27bSRobert Mustacchi 
3907eef4f27bSRobert Mustacchi /*******************************************************************************
3908eef4f27bSRobert Mustacchi  * Description:
3909eef4f27bSRobert Mustacchi  *
3910eef4f27bSRobert Mustacchi  * Return:
3911eef4f27bSRobert Mustacchi  ******************************************************************************/
3912eef4f27bSRobert Mustacchi STATIC u32_t
init_nwuf(lm_device_t * pdev,lm_nwuf_list_t * nwuf_list)3913eef4f27bSRobert Mustacchi init_nwuf(
3914eef4f27bSRobert Mustacchi     lm_device_t *pdev,
3915eef4f27bSRobert Mustacchi     lm_nwuf_list_t *nwuf_list)
3916eef4f27bSRobert Mustacchi {
3917eef4f27bSRobert Mustacchi     u32_t nwuf_cnt;
3918eef4f27bSRobert Mustacchi 
3919eef4f27bSRobert Mustacchi     if(CHIP_NUM(pdev) == CHIP_NUM_5706 || CHIP_NUM(pdev) == CHIP_NUM_5708)
3920eef4f27bSRobert Mustacchi     {
3921eef4f27bSRobert Mustacchi         nwuf_cnt = init_nwuf_5706(pdev, nwuf_list);
3922eef4f27bSRobert Mustacchi     }
3923eef4f27bSRobert Mustacchi     else
3924eef4f27bSRobert Mustacchi     {
3925eef4f27bSRobert Mustacchi         nwuf_cnt = init_nwuf_5709(pdev, nwuf_list);
3926eef4f27bSRobert Mustacchi     }
3927eef4f27bSRobert Mustacchi 
3928eef4f27bSRobert Mustacchi     return nwuf_cnt;
3929eef4f27bSRobert Mustacchi } /* init_nwuf */
3930eef4f27bSRobert Mustacchi 
3931eef4f27bSRobert Mustacchi 
3932eef4f27bSRobert Mustacchi 
3933eef4f27bSRobert Mustacchi /*******************************************************************************
3934eef4f27bSRobert Mustacchi  * Description:
3935eef4f27bSRobert Mustacchi  *
3936eef4f27bSRobert Mustacchi  * Return:
3937eef4f27bSRobert Mustacchi  ******************************************************************************/
3938eef4f27bSRobert Mustacchi STATIC void
set_d0_power_state(lm_device_t * pdev,u8_t set_pci_pm)3939eef4f27bSRobert Mustacchi set_d0_power_state(
3940eef4f27bSRobert Mustacchi     lm_device_t *pdev,
3941eef4f27bSRobert Mustacchi     u8_t set_pci_pm)
3942eef4f27bSRobert Mustacchi {
3943eef4f27bSRobert Mustacchi     u32_t val;
3944eef4f27bSRobert Mustacchi     u32_t idx;
3945eef4f27bSRobert Mustacchi 
3946eef4f27bSRobert Mustacchi     /* This step should be done by the OS or the caller.  Windows is
3947eef4f27bSRobert Mustacchi      * already doing this. */
3948eef4f27bSRobert Mustacchi     if(set_pci_pm)
3949eef4f27bSRobert Mustacchi     {
3950eef4f27bSRobert Mustacchi         /* Set the device to D0 state.  If a device is already in D3 state,
3951eef4f27bSRobert Mustacchi          * we will not be able to read the PCICFG_PM_CSR register using the
3952eef4f27bSRobert Mustacchi          * PCI memory command, we need to use config access here. */
3953eef4f27bSRobert Mustacchi         (void) mm_read_pci(
3954eef4f27bSRobert Mustacchi             pdev,
3955eef4f27bSRobert Mustacchi             OFFSETOF(reg_space_t, pci_config.pcicfg_pm_csr),
3956eef4f27bSRobert Mustacchi             &val);
3957eef4f27bSRobert Mustacchi 
3958eef4f27bSRobert Mustacchi         /* Set the device to D0 state.  This may be already done by the OS. */
3959eef4f27bSRobert Mustacchi         val &= ~PCICFG_PM_CSR_STATE;
3960eef4f27bSRobert Mustacchi         val |= PCICFG_PM_CSR_STATE_D0 | PCICFG_PM_CSR_PME_STATUS;
3961eef4f27bSRobert Mustacchi 
3962eef4f27bSRobert Mustacchi         (void) mm_write_pci(
3963eef4f27bSRobert Mustacchi             pdev,
3964eef4f27bSRobert Mustacchi             OFFSETOF(reg_space_t, pci_config.pcicfg_pm_csr),
3965eef4f27bSRobert Mustacchi             val);
3966eef4f27bSRobert Mustacchi     }
3967eef4f27bSRobert Mustacchi 
3968eef4f27bSRobert Mustacchi     /* With 5706_A1, the chip gets a reset coming out of D3.  Wait
3969eef4f27bSRobert Mustacchi      * for the boot to code finish running before we continue.  Without
3970eef4f27bSRobert Mustacchi      * this wait, we could run into lockup or the PHY may not work. */
3971eef4f27bSRobert Mustacchi     if(CHIP_ID(pdev) == CHIP_ID_5706_A1)
3972eef4f27bSRobert Mustacchi     {
3973eef4f27bSRobert Mustacchi         for(idx = 0; idx < 1000; idx++)
3974eef4f27bSRobert Mustacchi         {
3975eef4f27bSRobert Mustacchi             mm_wait(pdev, 15);
3976eef4f27bSRobert Mustacchi         }
3977eef4f27bSRobert Mustacchi     }
3978eef4f27bSRobert Mustacchi 
3979eef4f27bSRobert Mustacchi     /* Clear the ACPI_RCVD and MPKT_RCVD bits and disable magic packet. */
3980eef4f27bSRobert Mustacchi     REG_RD(pdev, emac.emac_mode, &val);
3981eef4f27bSRobert Mustacchi     val |= EMAC_MODE_MPKT_RCVD | EMAC_MODE_ACPI_RCVD;
3982eef4f27bSRobert Mustacchi     val &= ~EMAC_MODE_MPKT;
3983eef4f27bSRobert Mustacchi     REG_WR(pdev, emac.emac_mode, val);
3984eef4f27bSRobert Mustacchi 
3985eef4f27bSRobert Mustacchi     /* Disable interesting packet detection. */
3986eef4f27bSRobert Mustacchi     REG_RD(pdev, rpm.rpm_config, &val);
3987eef4f27bSRobert Mustacchi     val &= ~RPM_CONFIG_ACPI_ENA;
3988eef4f27bSRobert Mustacchi     REG_WR(pdev, rpm.rpm_config, val);
3989eef4f27bSRobert Mustacchi } /* set_d0_power_state */
3990eef4f27bSRobert Mustacchi 
3991eef4f27bSRobert Mustacchi 
3992eef4f27bSRobert Mustacchi 
3993eef4f27bSRobert Mustacchi /*******************************************************************************
3994eef4f27bSRobert Mustacchi  * Description:
3995eef4f27bSRobert Mustacchi  *
3996eef4f27bSRobert Mustacchi  * Return:
3997eef4f27bSRobert Mustacchi  ******************************************************************************/
3998eef4f27bSRobert Mustacchi STATIC void
set_d3_power_state(lm_device_t * pdev,lm_wake_up_mode_t wake_up_mode,u8_t set_pci_pm)3999eef4f27bSRobert Mustacchi set_d3_power_state(
4000eef4f27bSRobert Mustacchi     lm_device_t *pdev,
4001eef4f27bSRobert Mustacchi     lm_wake_up_mode_t wake_up_mode,
4002eef4f27bSRobert Mustacchi     u8_t set_pci_pm)
4003eef4f27bSRobert Mustacchi {
4004eef4f27bSRobert Mustacchi     u32_t fw_timed_out;
4005eef4f27bSRobert Mustacchi     u32_t reset_reason;
4006eef4f27bSRobert Mustacchi     u32_t gpio_pin;
4007eef4f27bSRobert Mustacchi     u32_t val;
4008eef4f27bSRobert Mustacchi     u32_t cnt;
4009eef4f27bSRobert Mustacchi 
4010eef4f27bSRobert Mustacchi     /* Set up magic and interesting packet detection. */
4011eef4f27bSRobert Mustacchi     if(wake_up_mode & (LM_WAKE_UP_MODE_MAGIC_PACKET | LM_WAKE_UP_MODE_NWUF))
4012eef4f27bSRobert Mustacchi     {
4013eef4f27bSRobert Mustacchi         /* Enable magic packet detection. */
4014eef4f27bSRobert Mustacchi         REG_RD(pdev, emac.emac_mode, &val);
4015eef4f27bSRobert Mustacchi         if(wake_up_mode & LM_WAKE_UP_MODE_MAGIC_PACKET)
4016eef4f27bSRobert Mustacchi         {
4017eef4f27bSRobert Mustacchi             val |= EMAC_MODE_MPKT;
4018eef4f27bSRobert Mustacchi         }
4019eef4f27bSRobert Mustacchi         else
4020eef4f27bSRobert Mustacchi         {
4021eef4f27bSRobert Mustacchi             val &= ~EMAC_MODE_MPKT;
4022eef4f27bSRobert Mustacchi         }
4023eef4f27bSRobert Mustacchi 
4024eef4f27bSRobert Mustacchi         /* Enable port mode. */
4025eef4f27bSRobert Mustacchi         val &= ~EMAC_MODE_PORT;
4026eef4f27bSRobert Mustacchi         if(CHIP_REV(pdev) == CHIP_REV_FPGA || CHIP_REV(pdev) == CHIP_REV_IKOS)
4027eef4f27bSRobert Mustacchi         {
4028eef4f27bSRobert Mustacchi             /* IKOS or FPGA always run in GMII mode even if its actual
4029eef4f27bSRobert Mustacchi              * link speed is 10mb or 100mb. */
4030eef4f27bSRobert Mustacchi             val |= EMAC_MODE_PORT_GMII;
4031eef4f27bSRobert Mustacchi         }
4032eef4f27bSRobert Mustacchi         else
4033eef4f27bSRobert Mustacchi         {
4034eef4f27bSRobert Mustacchi             val |= EMAC_MODE_PORT_MII;
4035eef4f27bSRobert Mustacchi         }
4036eef4f27bSRobert Mustacchi         val |= EMAC_MODE_MPKT_RCVD | EMAC_MODE_ACPI_RCVD;
4037eef4f27bSRobert Mustacchi 
4038eef4f27bSRobert Mustacchi         REG_WR(pdev, emac.emac_mode, val);
4039eef4f27bSRobert Mustacchi 
4040eef4f27bSRobert Mustacchi         /* Set up the receive mask. */
4041eef4f27bSRobert Mustacchi         (void) lm_set_rx_mask(
4042eef4f27bSRobert Mustacchi             pdev,
4043eef4f27bSRobert Mustacchi             RX_FILTER_USER_IDX0,
4044eef4f27bSRobert Mustacchi             LM_RX_MASK_ACCEPT_UNICAST |
4045eef4f27bSRobert Mustacchi                 LM_RX_MASK_ACCEPT_ALL_MULTICAST |
4046eef4f27bSRobert Mustacchi                 LM_RX_MASK_ACCEPT_BROADCAST);
4047eef4f27bSRobert Mustacchi 
4048eef4f27bSRobert Mustacchi         /* The first four address slots are use for magic packet detection.
4049eef4f27bSRobert Mustacchi          * we need to initialize all four address slots. */
4050eef4f27bSRobert Mustacchi         for(cnt = 0; cnt < 4; cnt++)
4051eef4f27bSRobert Mustacchi         {
4052eef4f27bSRobert Mustacchi             (void) lm_set_mac_addr(pdev, cnt, pdev->params.mac_addr);
4053eef4f27bSRobert Mustacchi         }
4054eef4f27bSRobert Mustacchi 
4055eef4f27bSRobert Mustacchi         /* Need to enable EMAC and RPM for WOL. */
4056eef4f27bSRobert Mustacchi         REG_WR(
4057eef4f27bSRobert Mustacchi             pdev,
4058eef4f27bSRobert Mustacchi             misc.misc_enable_set_bits,
4059eef4f27bSRobert Mustacchi             MISC_ENABLE_SET_BITS_RX_PARSER_MAC_ENABLE |
4060eef4f27bSRobert Mustacchi                 MISC_ENABLE_SET_BITS_TX_HEADER_Q_ENABLE |
4061eef4f27bSRobert Mustacchi                 MISC_ENABLE_SET_BITS_EMAC_ENABLE);
4062eef4f27bSRobert Mustacchi 
4063eef4f27bSRobert Mustacchi         /* Enable interesting packet detection.  This must be done after
4064eef4f27bSRobert Mustacchi          * the necessary blocks are enabled, otherwise we may wake-up on
4065eef4f27bSRobert Mustacchi          * a bogus first packet.  Need to document this in prm. */
4066eef4f27bSRobert Mustacchi         REG_RD(pdev, rpm.rpm_config, &val);
4067eef4f27bSRobert Mustacchi         if(wake_up_mode & LM_WAKE_UP_MODE_NWUF)
4068eef4f27bSRobert Mustacchi         {
4069eef4f27bSRobert Mustacchi             REG_WR(pdev, rpm.rpm_config, val & ~RPM_CONFIG_ACPI_ENA);
4070eef4f27bSRobert Mustacchi 
4071eef4f27bSRobert Mustacchi             /* Also need to be documented in the prm - to prevent a false
4072eef4f27bSRobert Mustacchi              * detection, we need to disable ACP_EN if there is no pattern
4073eef4f27bSRobert Mustacchi              * programmed.  There is no way of preventing false detection
4074eef4f27bSRobert Mustacchi              * by intializing the pattern buffer a certain way. */
4075eef4f27bSRobert Mustacchi             if(init_nwuf(pdev, &pdev->nwuf_list))
4076eef4f27bSRobert Mustacchi             {
4077eef4f27bSRobert Mustacchi                 val |= RPM_CONFIG_ACPI_ENA;
4078eef4f27bSRobert Mustacchi             }
4079eef4f27bSRobert Mustacchi             else
4080eef4f27bSRobert Mustacchi             {
4081eef4f27bSRobert Mustacchi                 val &= ~RPM_CONFIG_ACPI_ENA;
4082eef4f27bSRobert Mustacchi             }
4083eef4f27bSRobert Mustacchi         }
4084eef4f27bSRobert Mustacchi         else
4085eef4f27bSRobert Mustacchi         {
4086eef4f27bSRobert Mustacchi             val &= ~RPM_CONFIG_ACPI_ENA;
4087eef4f27bSRobert Mustacchi         }
4088eef4f27bSRobert Mustacchi         REG_WR(pdev, rpm.rpm_config, val);
4089eef4f27bSRobert Mustacchi 
4090eef4f27bSRobert Mustacchi         /* xinan requires rbuf to be enabled.  enabling it for teton
4091eef4f27bSRobert Mustacchi          * does not hurt. */
4092eef4f27bSRobert Mustacchi         REG_WR(
4093eef4f27bSRobert Mustacchi             pdev,
4094eef4f27bSRobert Mustacchi             misc.misc_enable_set_bits,
4095eef4f27bSRobert Mustacchi             MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE);
4096eef4f27bSRobert Mustacchi 
4097eef4f27bSRobert Mustacchi         reset_reason = LM_REASON_WOL_SUSPEND;
4098eef4f27bSRobert Mustacchi     }
4099eef4f27bSRobert Mustacchi     else
4100eef4f27bSRobert Mustacchi     {
4101eef4f27bSRobert Mustacchi         reset_reason = LM_REASON_NO_WOL_SUSPEND;
4102eef4f27bSRobert Mustacchi     }
4103eef4f27bSRobert Mustacchi 
4104eef4f27bSRobert Mustacchi     /* Allow the firmware to make any final changes to the chip before
4105eef4f27bSRobert Mustacchi      * we go into D3 mode.  The timeout period is longer because the
4106eef4f27bSRobert Mustacchi      * firwmare could take more time to download management firmware
4107eef4f27bSRobert Mustacchi      * which occurs during this stage of the reset. */
4108eef4f27bSRobert Mustacchi     fw_timed_out = fw_reset_sync(
4109eef4f27bSRobert Mustacchi         pdev,
4110eef4f27bSRobert Mustacchi         reset_reason,
4111eef4f27bSRobert Mustacchi         DRV_MSG_DATA_WAIT3,
4112eef4f27bSRobert Mustacchi         FW_ACK_TIME_OUT_MS*1000 * 3);
4113eef4f27bSRobert Mustacchi 
4114eef4f27bSRobert Mustacchi     /* If the firmware is not running, we have to switch to vaux power,
4115eef4f27bSRobert Mustacchi      * otherwise let the firmware do it. */
4116eef4f27bSRobert Mustacchi     if(fw_timed_out)
4117eef4f27bSRobert Mustacchi     {
4118eef4f27bSRobert Mustacchi         /* Power down the PHY. */
4119eef4f27bSRobert Mustacchi         if(pdev->params.enable_remote_phy == FALSE)
4120eef4f27bSRobert Mustacchi         {
4121eef4f27bSRobert Mustacchi             if(CHIP_REV(pdev) != CHIP_REV_FPGA &&
4122eef4f27bSRobert Mustacchi                 CHIP_REV(pdev) != CHIP_REV_IKOS)
4123eef4f27bSRobert Mustacchi             {
4124eef4f27bSRobert Mustacchi                 (void) lm_mwrite(
4125eef4f27bSRobert Mustacchi                     pdev,
4126eef4f27bSRobert Mustacchi                     pdev->params.phy_addr,
4127eef4f27bSRobert Mustacchi                     0x1c,
4128eef4f27bSRobert Mustacchi                     0xa821);
4129eef4f27bSRobert Mustacchi             }
4130eef4f27bSRobert Mustacchi         }
4131eef4f27bSRobert Mustacchi 
4132eef4f27bSRobert Mustacchi         /* Minimum core clock for a particular link.
4133eef4f27bSRobert Mustacchi          *    10Mb      core_clk = 6.25Mhz
4134eef4f27bSRobert Mustacchi          *    100Mb     core_clk = 12Mhz
4135eef4f27bSRobert Mustacchi          *    1Gb       core_clk = 100Mhz (use PLL)
4136eef4f27bSRobert Mustacchi          *
4137eef4f27bSRobert Mustacchi          * The driver is configured to autoneg to 10/100Mb for WOL mode.  So
4138eef4f27bSRobert Mustacchi          * the core clock needs to be configured to 12Mhz. */
4139eef4f27bSRobert Mustacchi         REG_RD(pdev, misc.misc_clock_control_bits, &val);
4140eef4f27bSRobert Mustacchi         val &= ~(MISC_CLOCK_CONTROL_BITS_CORE_CLK_DISABLE |
4141eef4f27bSRobert Mustacchi             MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT |
4142eef4f27bSRobert Mustacchi             MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_TE);
4143eef4f27bSRobert Mustacchi 
4144eef4f27bSRobert Mustacchi         /* Select the 12.5m alt clock. */
4145eef4f27bSRobert Mustacchi         REG_WR(
4146eef4f27bSRobert Mustacchi             pdev,
4147eef4f27bSRobert Mustacchi             misc.misc_clock_control_bits,
4148eef4f27bSRobert Mustacchi             MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_12_TE | val);
4149eef4f27bSRobert Mustacchi 
4150eef4f27bSRobert Mustacchi         /* Switch to the alt clock. */
4151eef4f27bSRobert Mustacchi         REG_WR(
4152eef4f27bSRobert Mustacchi             pdev,
4153eef4f27bSRobert Mustacchi             misc.misc_clock_control_bits,
4154eef4f27bSRobert Mustacchi             MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_12_TE |
4155eef4f27bSRobert Mustacchi                 MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT |
4156eef4f27bSRobert Mustacchi                 val);
4157eef4f27bSRobert Mustacchi 
4158eef4f27bSRobert Mustacchi         /* Disable core clock to non-wol blocks. */
4159eef4f27bSRobert Mustacchi         REG_WR(
4160eef4f27bSRobert Mustacchi             pdev,
4161eef4f27bSRobert Mustacchi             misc.misc_clock_control_bits,
4162eef4f27bSRobert Mustacchi             MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_12_TE |
4163eef4f27bSRobert Mustacchi                 MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT |
4164eef4f27bSRobert Mustacchi                 MISC_CLOCK_CONTROL_BITS_CORE_CLK_DISABLE |
4165eef4f27bSRobert Mustacchi                 val);
4166eef4f27bSRobert Mustacchi 
4167eef4f27bSRobert Mustacchi         gpio_pin = 1 << 2;  /* GPIO 2 */
4168eef4f27bSRobert Mustacchi 
4169eef4f27bSRobert Mustacchi         /* Switch to vaux power by bring GPIO2 to low. */
4170eef4f27bSRobert Mustacchi         REG_RD(pdev, misc.misc_spio, &val);
4171eef4f27bSRobert Mustacchi         val &= ~(gpio_pin << 24);           /* use this gpio as output. */
4172eef4f27bSRobert Mustacchi         val |= gpio_pin << 16;              /* clear the gpio. */
4173eef4f27bSRobert Mustacchi         REG_WR(pdev, misc.misc_spio, val);
4174eef4f27bSRobert Mustacchi 
4175eef4f27bSRobert Mustacchi         /* This step should be done by the OS or the caller.  Windows is
4176eef4f27bSRobert Mustacchi          * already doing this. */
4177eef4f27bSRobert Mustacchi         if(set_pci_pm)
4178eef4f27bSRobert Mustacchi         {
4179eef4f27bSRobert Mustacchi             /* Set the device to D3 state. */
4180eef4f27bSRobert Mustacchi             REG_RD_OFFSET(
4181eef4f27bSRobert Mustacchi                 pdev,
4182eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, pci_config.pcicfg_pm_csr),
4183eef4f27bSRobert Mustacchi                 &val);
4184eef4f27bSRobert Mustacchi 
4185eef4f27bSRobert Mustacchi             val &= ~PCICFG_PM_CSR_STATE;
4186eef4f27bSRobert Mustacchi             val |= PCICFG_PM_CSR_STATE_D3_HOT;
4187eef4f27bSRobert Mustacchi 
4188eef4f27bSRobert Mustacchi             REG_WR_OFFSET(
4189eef4f27bSRobert Mustacchi                 pdev,
4190eef4f27bSRobert Mustacchi                 OFFSETOF(reg_space_t, pci_config.pcicfg_pm_csr),
4191eef4f27bSRobert Mustacchi                 val);
4192eef4f27bSRobert Mustacchi         }
4193eef4f27bSRobert Mustacchi     }
4194eef4f27bSRobert Mustacchi } /* set_d3_power_state */
4195eef4f27bSRobert Mustacchi 
4196eef4f27bSRobert Mustacchi 
4197eef4f27bSRobert Mustacchi 
4198eef4f27bSRobert Mustacchi /*******************************************************************************
4199eef4f27bSRobert Mustacchi  * Description:
4200eef4f27bSRobert Mustacchi  *
4201eef4f27bSRobert Mustacchi  * Return:
4202eef4f27bSRobert Mustacchi  ******************************************************************************/
4203eef4f27bSRobert Mustacchi void
lm_set_power_state(lm_device_t * pdev,lm_power_state_t power_state,lm_wake_up_mode_t wake_up_mode,u8_t set_pci_pm)4204eef4f27bSRobert Mustacchi lm_set_power_state(
4205eef4f27bSRobert Mustacchi     lm_device_t *pdev,
4206eef4f27bSRobert Mustacchi     lm_power_state_t power_state,
4207eef4f27bSRobert Mustacchi     lm_wake_up_mode_t wake_up_mode,     /* Valid when power_state is D3. */
4208eef4f27bSRobert Mustacchi     u8_t set_pci_pm)
4209eef4f27bSRobert Mustacchi {
4210eef4f27bSRobert Mustacchi     if(power_state == LM_POWER_STATE_D0)
4211eef4f27bSRobert Mustacchi     {
4212eef4f27bSRobert Mustacchi         set_d0_power_state(pdev, set_pci_pm);
4213eef4f27bSRobert Mustacchi     }
4214eef4f27bSRobert Mustacchi     else
4215eef4f27bSRobert Mustacchi     {
4216eef4f27bSRobert Mustacchi         set_d3_power_state(pdev, wake_up_mode, set_pci_pm);
4217eef4f27bSRobert Mustacchi     }
4218eef4f27bSRobert Mustacchi } /* lm_set_power_state */
4219eef4f27bSRobert Mustacchi 
4220eef4f27bSRobert Mustacchi 
4221eef4f27bSRobert Mustacchi 
4222eef4f27bSRobert Mustacchi #ifndef EXCLUDE_KQE_SUPPORT
4223eef4f27bSRobert Mustacchi /*******************************************************************************
4224eef4f27bSRobert Mustacchi  * Description:
4225eef4f27bSRobert Mustacchi  *
4226eef4f27bSRobert Mustacchi  * Return:
4227eef4f27bSRobert Mustacchi  ******************************************************************************/
4228eef4f27bSRobert Mustacchi u32_t
lm_submit_kernel_wqes(lm_device_t * pdev,kwqe_t * wqes[],u32_t num_wqes)4229eef4f27bSRobert Mustacchi lm_submit_kernel_wqes(
4230eef4f27bSRobert Mustacchi     lm_device_t *pdev,
4231eef4f27bSRobert Mustacchi     kwqe_t *wqes[],
4232eef4f27bSRobert Mustacchi     u32_t num_wqes)
4233eef4f27bSRobert Mustacchi {
4234eef4f27bSRobert Mustacchi     kwqe_t *prod_qe;
4235eef4f27bSRobert Mustacchi     u16_t prod_idx;
4236eef4f27bSRobert Mustacchi     u32_t qe_cnt;
4237eef4f27bSRobert Mustacchi 
4238eef4f27bSRobert Mustacchi     if(num_wqes > pdev->kq_info.kwqe_left)
4239eef4f27bSRobert Mustacchi     {
4240eef4f27bSRobert Mustacchi         pdev->kq_info.no_kwq_bd_left++;
4241eef4f27bSRobert Mustacchi 
4242eef4f27bSRobert Mustacchi         return 0;
4243eef4f27bSRobert Mustacchi     }
4244eef4f27bSRobert Mustacchi 
4245eef4f27bSRobert Mustacchi     pdev->kq_info.kwqe_left -= num_wqes;
4246eef4f27bSRobert Mustacchi 
4247eef4f27bSRobert Mustacchi     prod_qe = pdev->kq_info.kwq_prod_qe;
4248eef4f27bSRobert Mustacchi     prod_idx = pdev->kq_info.kwq_prod_idx;
4249eef4f27bSRobert Mustacchi 
4250eef4f27bSRobert Mustacchi     qe_cnt = num_wqes;
4251eef4f27bSRobert Mustacchi     while(qe_cnt)
4252eef4f27bSRobert Mustacchi     {
4253eef4f27bSRobert Mustacchi         *prod_qe = *(*wqes);
4254eef4f27bSRobert Mustacchi 
4255eef4f27bSRobert Mustacchi         if(prod_qe == pdev->kq_info.kwq_last_qe)
4256eef4f27bSRobert Mustacchi         {
4257eef4f27bSRobert Mustacchi             prod_qe = pdev->kq_info.kwq_virt;
4258eef4f27bSRobert Mustacchi         }
4259eef4f27bSRobert Mustacchi         else
4260eef4f27bSRobert Mustacchi         {
4261eef4f27bSRobert Mustacchi             prod_qe++;
4262eef4f27bSRobert Mustacchi         }
4263eef4f27bSRobert Mustacchi 
4264eef4f27bSRobert Mustacchi         wqes++;
4265eef4f27bSRobert Mustacchi         prod_idx++;
4266eef4f27bSRobert Mustacchi         qe_cnt--;
4267eef4f27bSRobert Mustacchi     }
4268eef4f27bSRobert Mustacchi 
4269eef4f27bSRobert Mustacchi     pdev->kq_info.kwq_prod_qe = prod_qe;
4270eef4f27bSRobert Mustacchi     pdev->kq_info.kwq_prod_idx = prod_idx;
4271eef4f27bSRobert Mustacchi 
4272eef4f27bSRobert Mustacchi     MBQ_WR16(
4273eef4f27bSRobert Mustacchi         pdev,
4274eef4f27bSRobert Mustacchi         GET_CID(pdev->kq_info.kwq_cid_addr),
4275eef4f27bSRobert Mustacchi         OFFSETOF(krnlq_context_t, krnlq_host_qidx),
4276eef4f27bSRobert Mustacchi         prod_idx);
4277eef4f27bSRobert Mustacchi 
4278eef4f27bSRobert Mustacchi     return num_wqes;
4279eef4f27bSRobert Mustacchi } /* lm_submit_kernel_wqes */
4280eef4f27bSRobert Mustacchi #endif /* EXCLUDE_KQE_SUPPORT */
4281eef4f27bSRobert Mustacchi 
4282eef4f27bSRobert Mustacchi 
4283eef4f27bSRobert Mustacchi 
4284eef4f27bSRobert Mustacchi /*******************************************************************************
4285eef4f27bSRobert Mustacchi  * Description:
4286eef4f27bSRobert Mustacchi  *
4287eef4f27bSRobert Mustacchi  * Return:
4288eef4f27bSRobert Mustacchi  ******************************************************************************/
4289eef4f27bSRobert Mustacchi lm_interrupt_status_t
lm_get_interrupt_status(lm_device_t * pdev)4290eef4f27bSRobert Mustacchi lm_get_interrupt_status(
4291eef4f27bSRobert Mustacchi     lm_device_t *pdev)
4292eef4f27bSRobert Mustacchi {
4293eef4f27bSRobert Mustacchi     lm_interrupt_status_t intr_status;
4294eef4f27bSRobert Mustacchi     u32_t deasserted_attns;
4295eef4f27bSRobert Mustacchi     u32_t asserted_attns;
4296eef4f27bSRobert Mustacchi     lm_rx_chain_t *rxq;
4297eef4f27bSRobert Mustacchi     lm_tx_chain_t *txq;
4298eef4f27bSRobert Mustacchi     u16_t hw_con_idx;
4299eef4f27bSRobert Mustacchi     u32_t val;
4300eef4f27bSRobert Mustacchi     u32_t idx;
4301eef4f27bSRobert Mustacchi 
4302eef4f27bSRobert Mustacchi     intr_status = LM_NO_EVENT_ACTIVE;
4303eef4f27bSRobert Mustacchi 
4304eef4f27bSRobert Mustacchi     /* Determine link change status. */
4305eef4f27bSRobert Mustacchi     if(pdev->params.link_chng_mode == LINK_CHNG_MODE_USE_STATUS_REG)
4306eef4f27bSRobert Mustacchi     {
4307eef4f27bSRobert Mustacchi         REG_RD(pdev, emac.emac_status, &val);
4308eef4f27bSRobert Mustacchi         if(pdev->params.phy_int_mode == PHY_INT_MODE_MI_INTERRUPT)
4309eef4f27bSRobert Mustacchi         {
4310eef4f27bSRobert Mustacchi             if(val & EMAC_STATUS_MI_INT)
4311eef4f27bSRobert Mustacchi             {
4312eef4f27bSRobert Mustacchi                 intr_status |= LM_PHY_EVENT_ACTIVE;
4313eef4f27bSRobert Mustacchi             }
4314eef4f27bSRobert Mustacchi         }
4315eef4f27bSRobert Mustacchi         else if(val & EMAC_STATUS_LINK_CHANGE)
4316eef4f27bSRobert Mustacchi         {
4317eef4f27bSRobert Mustacchi             intr_status |= LM_PHY_EVENT_ACTIVE;
4318eef4f27bSRobert Mustacchi         }
4319eef4f27bSRobert Mustacchi 
4320eef4f27bSRobert Mustacchi         GET_ATTN_CHNG_BITS(pdev, &asserted_attns, &deasserted_attns);
4321eef4f27bSRobert Mustacchi     }
4322eef4f27bSRobert Mustacchi     else
4323eef4f27bSRobert Mustacchi     {
4324eef4f27bSRobert Mustacchi         GET_ATTN_CHNG_BITS(pdev, &asserted_attns, &deasserted_attns);
4325eef4f27bSRobert Mustacchi 
4326eef4f27bSRobert Mustacchi         if(asserted_attns & STATUS_ATTN_BITS_LINK_STATE)
4327eef4f27bSRobert Mustacchi         {
4328eef4f27bSRobert Mustacchi             intr_status |= LM_PHY_EVENT_ACTIVE;
4329eef4f27bSRobert Mustacchi         }
4330eef4f27bSRobert Mustacchi         else if(deasserted_attns & STATUS_ATTN_BITS_LINK_STATE)
4331eef4f27bSRobert Mustacchi         {
4332eef4f27bSRobert Mustacchi             intr_status |= LM_PHY_EVENT_ACTIVE;
4333eef4f27bSRobert Mustacchi         }
4334eef4f27bSRobert Mustacchi     }
4335eef4f27bSRobert Mustacchi 
4336eef4f27bSRobert Mustacchi     /* Get driver pulse event.  MCP uses the TIMER_ABORT attention to
4337eef4f27bSRobert Mustacchi      * signal to the driver to write a driver pulse to the firmware. */
4338eef4f27bSRobert Mustacchi     if((asserted_attns & STATUS_ATTN_BITS_TIMER_ABORT) ||
4339eef4f27bSRobert Mustacchi         (deasserted_attns & STATUS_ATTN_BITS_TIMER_ABORT))
4340eef4f27bSRobert Mustacchi     {
4341eef4f27bSRobert Mustacchi         if(pdev->params.enable_remote_phy)
4342eef4f27bSRobert Mustacchi         {
4343eef4f27bSRobert Mustacchi             REG_RD_IND(
4344eef4f27bSRobert Mustacchi                 pdev,
4345eef4f27bSRobert Mustacchi                 pdev->hw_info.shmem_base +
4346eef4f27bSRobert Mustacchi                     OFFSETOF(shmem_region_t, fw_evt_mb.fw_evt_code_mb),
4347eef4f27bSRobert Mustacchi                 &val);
4348eef4f27bSRobert Mustacchi 
4349eef4f27bSRobert Mustacchi             if(val == 0)
4350eef4f27bSRobert Mustacchi             {
4351eef4f27bSRobert Mustacchi                 intr_status |= LM_KNOCK_KNOCK_EVENT;
4352eef4f27bSRobert Mustacchi             }
4353eef4f27bSRobert Mustacchi             else if(val == FW_EVT_CODE_LINK_STATUS_CHANGE_EVENT)
4354eef4f27bSRobert Mustacchi             {
4355eef4f27bSRobert Mustacchi                 intr_status |= LM_PHY_EVENT_ACTIVE;
4356eef4f27bSRobert Mustacchi             }
4357eef4f27bSRobert Mustacchi             else
4358eef4f27bSRobert Mustacchi             {
4359eef4f27bSRobert Mustacchi                 DbgBreakMsg("not a valid fw event.\n");
4360eef4f27bSRobert Mustacchi             }
4361eef4f27bSRobert Mustacchi         }
4362eef4f27bSRobert Mustacchi         else
4363eef4f27bSRobert Mustacchi         {
4364eef4f27bSRobert Mustacchi             intr_status |= LM_KNOCK_KNOCK_EVENT;
4365eef4f27bSRobert Mustacchi         }
4366eef4f27bSRobert Mustacchi 
4367eef4f27bSRobert Mustacchi         if(asserted_attns & STATUS_ATTN_BITS_TIMER_ABORT)
4368eef4f27bSRobert Mustacchi         {
4369eef4f27bSRobert Mustacchi             REG_WR(
4370eef4f27bSRobert Mustacchi                 pdev,
4371eef4f27bSRobert Mustacchi                 pci_config.pcicfg_status_bit_set_cmd,
4372eef4f27bSRobert Mustacchi                 asserted_attns & STATUS_ATTN_BITS_TIMER_ABORT);
4373eef4f27bSRobert Mustacchi         }
4374eef4f27bSRobert Mustacchi         else
4375eef4f27bSRobert Mustacchi         {
4376eef4f27bSRobert Mustacchi             REG_WR(
4377eef4f27bSRobert Mustacchi                 pdev,
4378eef4f27bSRobert Mustacchi                 pci_config.pcicfg_status_bit_clear_cmd,
4379eef4f27bSRobert Mustacchi                 deasserted_attns & STATUS_ATTN_BITS_TIMER_ABORT);
4380eef4f27bSRobert Mustacchi         }
4381eef4f27bSRobert Mustacchi     }
4382eef4f27bSRobert Mustacchi 
4383eef4f27bSRobert Mustacchi     /* get l2 tx events. */
4384eef4f27bSRobert Mustacchi     for(idx = 0; idx < pdev->tx_info.num_txq; idx++)
4385eef4f27bSRobert Mustacchi     {
4386eef4f27bSRobert Mustacchi         txq = &pdev->tx_info.chain[idx];
4387eef4f27bSRobert Mustacchi 
4388eef4f27bSRobert Mustacchi         hw_con_idx = *txq->hw_con_idx_ptr;
4389eef4f27bSRobert Mustacchi         if((hw_con_idx & MAX_BD_PER_PAGE) == MAX_BD_PER_PAGE)
4390eef4f27bSRobert Mustacchi         {
4391eef4f27bSRobert Mustacchi             hw_con_idx++;
4392eef4f27bSRobert Mustacchi         }
4393eef4f27bSRobert Mustacchi 
4394eef4f27bSRobert Mustacchi         if(hw_con_idx != txq->con_idx)
4395eef4f27bSRobert Mustacchi         {
4396eef4f27bSRobert Mustacchi             intr_status |= LM_TX0_EVENT_ACTIVE << txq->idx;
4397eef4f27bSRobert Mustacchi         }
4398eef4f27bSRobert Mustacchi     }
4399eef4f27bSRobert Mustacchi 
4400eef4f27bSRobert Mustacchi     /* get l2 rx events. */
4401eef4f27bSRobert Mustacchi     for(idx = 0; idx < pdev->rx_info.num_rxq; idx++)
4402eef4f27bSRobert Mustacchi     {
4403eef4f27bSRobert Mustacchi         rxq = &pdev->rx_info.chain[idx];
4404eef4f27bSRobert Mustacchi 
4405eef4f27bSRobert Mustacchi         hw_con_idx = *rxq->hw_con_idx_ptr;
4406eef4f27bSRobert Mustacchi         if((hw_con_idx & MAX_BD_PER_PAGE) == MAX_BD_PER_PAGE)
4407eef4f27bSRobert Mustacchi         {
4408eef4f27bSRobert Mustacchi             hw_con_idx++;
4409eef4f27bSRobert Mustacchi         }
4410eef4f27bSRobert Mustacchi 
4411eef4f27bSRobert Mustacchi         if(hw_con_idx != rxq->con_idx)
4412eef4f27bSRobert Mustacchi         {
4413eef4f27bSRobert Mustacchi             intr_status |= LM_RX0_EVENT_ACTIVE << rxq->idx;
4414eef4f27bSRobert Mustacchi         }
4415eef4f27bSRobert Mustacchi     }
4416eef4f27bSRobert Mustacchi 
4417eef4f27bSRobert Mustacchi     #ifndef EXCLUDE_KQE_SUPPORT
4418eef4f27bSRobert Mustacchi     if(CHIP_NUM(pdev) == CHIP_NUM_5706 || CHIP_NUM(pdev) == CHIP_NUM_5708)
4419eef4f27bSRobert Mustacchi     {
4420eef4f27bSRobert Mustacchi         /* HC install problem:  as a workaround, rx_quick_consumer_index15
4421eef4f27bSRobert Mustacchi          * is high jacked for use as cmd_con_idx.  The original cmd_con_idx
4422eef4f27bSRobert Mustacchi          * is not used. */
4423eef4f27bSRobert Mustacchi         if(pdev->kq_info.kwq_con_idx !=
4424eef4f27bSRobert Mustacchi             pdev->vars.status_virt->deflt.status_rx_quick_consumer_index15)
4425eef4f27bSRobert Mustacchi         {
4426eef4f27bSRobert Mustacchi             intr_status |= LM_KWQ_EVENT_ACTIVE;
4427eef4f27bSRobert Mustacchi         }
4428eef4f27bSRobert Mustacchi     }
4429eef4f27bSRobert Mustacchi     else
4430eef4f27bSRobert Mustacchi     {
4431eef4f27bSRobert Mustacchi         if(pdev->kq_info.kwq_con_idx !=
4432eef4f27bSRobert Mustacchi             pdev->vars.status_virt->deflt.status_cmd_consumer_index)
4433eef4f27bSRobert Mustacchi         {
4434eef4f27bSRobert Mustacchi             intr_status |= LM_KWQ_EVENT_ACTIVE;
4435eef4f27bSRobert Mustacchi         }
4436eef4f27bSRobert Mustacchi     }
4437eef4f27bSRobert Mustacchi 
4438eef4f27bSRobert Mustacchi     if(pdev->kq_info.kcq_con_idx !=
4439eef4f27bSRobert Mustacchi         pdev->vars.status_virt->deflt.status_completion_producer_index)
4440eef4f27bSRobert Mustacchi     {
4441eef4f27bSRobert Mustacchi         intr_status |= LM_KCQ_EVENT_ACTIVE;
4442eef4f27bSRobert Mustacchi     }
4443eef4f27bSRobert Mustacchi     #endif
4444eef4f27bSRobert Mustacchi 
4445eef4f27bSRobert Mustacchi     #if INCLUDE_OFLD_SUPPORT
4446eef4f27bSRobert Mustacchi     else if(pdev->params.hcopy_desc_cnt)
4447eef4f27bSRobert Mustacchi     {
4448eef4f27bSRobert Mustacchi         if(pdev->ofld.hcopy_chain.con_idx !=
4449eef4f27bSRobert Mustacchi             *(pdev->ofld.hcopy_chain.hw_con_idx_ptr))
4450eef4f27bSRobert Mustacchi         {
4451eef4f27bSRobert Mustacchi             intr_status |= LM_KCQ_EVENT_ACTIVE;
4452eef4f27bSRobert Mustacchi         }
4453eef4f27bSRobert Mustacchi     }
4454eef4f27bSRobert Mustacchi     #endif
4455eef4f27bSRobert Mustacchi 
4456eef4f27bSRobert Mustacchi     return intr_status;
4457eef4f27bSRobert Mustacchi } /* lm_get_interrupt_status */
4458eef4f27bSRobert Mustacchi 
4459eef4f27bSRobert Mustacchi 
4460eef4f27bSRobert Mustacchi 
4461eef4f27bSRobert Mustacchi #ifndef EXCLUDE_KQE_SUPPORT
4462eef4f27bSRobert Mustacchi /*******************************************************************************
4463eef4f27bSRobert Mustacchi  * Description:
4464eef4f27bSRobert Mustacchi  *
4465eef4f27bSRobert Mustacchi  * Return:
4466eef4f27bSRobert Mustacchi  ******************************************************************************/
4467eef4f27bSRobert Mustacchi void
lm_ack_completed_wqes(lm_device_t * pdev)4468eef4f27bSRobert Mustacchi lm_ack_completed_wqes(
4469eef4f27bSRobert Mustacchi     lm_device_t *pdev)
4470eef4f27bSRobert Mustacchi {
4471eef4f27bSRobert Mustacchi     u16_t new_con_idx;
4472eef4f27bSRobert Mustacchi     kwqe_t *con_qe;
4473eef4f27bSRobert Mustacchi     u16_t num_wqes;
4474eef4f27bSRobert Mustacchi     u16_t con_idx;
4475eef4f27bSRobert Mustacchi 
4476eef4f27bSRobert Mustacchi     /* HC install problem:  as a workaround, rx_quick_consumer_index15
4477eef4f27bSRobert Mustacchi      * is high jacked for use as cmd_con_idx.  The original cmd_con_idx
4478eef4f27bSRobert Mustacchi      * is not used. */
4479eef4f27bSRobert Mustacchi     if(CHIP_NUM(pdev) == CHIP_NUM_5706 || CHIP_NUM(pdev) == CHIP_NUM_5708)
4480eef4f27bSRobert Mustacchi     {
4481eef4f27bSRobert Mustacchi         new_con_idx =
4482eef4f27bSRobert Mustacchi             pdev->vars.status_virt->deflt.status_rx_quick_consumer_index15;
4483eef4f27bSRobert Mustacchi     }
4484eef4f27bSRobert Mustacchi     else
4485eef4f27bSRobert Mustacchi     {
4486eef4f27bSRobert Mustacchi         new_con_idx = pdev->vars.status_virt->deflt.status_cmd_consumer_index;
4487eef4f27bSRobert Mustacchi     }
4488eef4f27bSRobert Mustacchi 
4489eef4f27bSRobert Mustacchi     num_wqes = (u16_t) S16_SUB(new_con_idx, pdev->kq_info.kwq_con_idx);
4490eef4f27bSRobert Mustacchi     pdev->kq_info.kwqe_left += num_wqes;
4491eef4f27bSRobert Mustacchi 
4492eef4f27bSRobert Mustacchi     con_idx = new_con_idx;
4493eef4f27bSRobert Mustacchi     con_qe = pdev->kq_info.kwq_con_qe + num_wqes;
4494eef4f27bSRobert Mustacchi 
4495eef4f27bSRobert Mustacchi     /* Check for con_qe wrap around. */
4496eef4f27bSRobert Mustacchi     if((u8_t *) con_qe > (u8_t *) pdev->kq_info.kwq_last_qe)
4497eef4f27bSRobert Mustacchi     {
4498eef4f27bSRobert Mustacchi         con_qe = (kwqe_t *) ((u8_t *) pdev->kq_info.kwq_virt +
4499eef4f27bSRobert Mustacchi             ((u8_t *) con_qe - (u8_t *) pdev->kq_info.kwq_last_qe));
4500eef4f27bSRobert Mustacchi         con_qe--;
4501eef4f27bSRobert Mustacchi     }
4502eef4f27bSRobert Mustacchi 
4503eef4f27bSRobert Mustacchi     pdev->kq_info.kwq_con_idx = con_idx;
4504eef4f27bSRobert Mustacchi     pdev->kq_info.kwq_con_qe = con_qe;
4505eef4f27bSRobert Mustacchi 
4506eef4f27bSRobert Mustacchi     /* Make sure the con_qe and con_idx are consistent. */
4507eef4f27bSRobert Mustacchi     DbgBreakIf(((((u8_t *) con_qe - (u8_t *) pdev->kq_info.kwq_virt) /
4508eef4f27bSRobert Mustacchi         sizeof(kwqe_t)) & 0x7f) != (con_idx & 0x7f));
4509eef4f27bSRobert Mustacchi 
4510eef4f27bSRobert Mustacchi     #if DBG
4511eef4f27bSRobert Mustacchi     /* Make sure all the kwqes are accounted for. */
4512eef4f27bSRobert Mustacchi     if(S16_SUB(pdev->kq_info.kwq_prod_idx, con_idx) >= 0)
4513eef4f27bSRobert Mustacchi     {
4514eef4f27bSRobert Mustacchi         num_wqes = pdev->kq_info.kwqe_left +
4515eef4f27bSRobert Mustacchi             (u32_t) S16_SUB(pdev->kq_info.kwq_prod_idx, con_idx);
4516eef4f27bSRobert Mustacchi     }
4517eef4f27bSRobert Mustacchi     else
4518eef4f27bSRobert Mustacchi     {
4519eef4f27bSRobert Mustacchi         num_wqes = pdev->kq_info.kwqe_left + 0x10000 - con_idx +
4520eef4f27bSRobert Mustacchi             pdev->kq_info.kwq_prod_idx;
4521eef4f27bSRobert Mustacchi     }
4522eef4f27bSRobert Mustacchi 
4523eef4f27bSRobert Mustacchi     DbgBreakIf(num_wqes != (LM_PAGE_SIZE/sizeof(kwqe_t)) *
4524eef4f27bSRobert Mustacchi         pdev->params.kwq_page_cnt - 1);
4525eef4f27bSRobert Mustacchi     #endif
4526eef4f27bSRobert Mustacchi } /* lm_ack_completed_wqes */
4527eef4f27bSRobert Mustacchi 
4528eef4f27bSRobert Mustacchi 
4529eef4f27bSRobert Mustacchi 
4530eef4f27bSRobert Mustacchi /*******************************************************************************
4531eef4f27bSRobert Mustacchi  * Description:
4532eef4f27bSRobert Mustacchi  *
4533eef4f27bSRobert Mustacchi  * Return:
4534eef4f27bSRobert Mustacchi  ******************************************************************************/
4535eef4f27bSRobert Mustacchi u32_t
lm_get_kernel_cqes(lm_device_t * pdev,kcqe_t * cqe_ptr[],u32_t ptr_cnt)4536eef4f27bSRobert Mustacchi lm_get_kernel_cqes(
4537eef4f27bSRobert Mustacchi     lm_device_t *pdev,
4538eef4f27bSRobert Mustacchi     kcqe_t *cqe_ptr[],
4539eef4f27bSRobert Mustacchi     u32_t ptr_cnt)
4540eef4f27bSRobert Mustacchi {
4541eef4f27bSRobert Mustacchi     kcqe_t *con_qe;
4542eef4f27bSRobert Mustacchi     u16_t prod_idx;
4543eef4f27bSRobert Mustacchi     u32_t num_cqes;
4544eef4f27bSRobert Mustacchi     u16_t con_idx;
4545eef4f27bSRobert Mustacchi 
4546eef4f27bSRobert Mustacchi     DbgMessage(pdev, VERBOSEint, "### lm_get_kernel_cqes\n");
4547eef4f27bSRobert Mustacchi 
4548eef4f27bSRobert Mustacchi     con_idx = pdev->kq_info.kcq_con_idx;
4549eef4f27bSRobert Mustacchi     con_qe = pdev->kq_info.kcq_con_qe;
4550eef4f27bSRobert Mustacchi 
4551eef4f27bSRobert Mustacchi     DbgBreakIf(((((u8_t *) con_qe - (u8_t *) pdev->kq_info.kcq_virt) /
4552eef4f27bSRobert Mustacchi         sizeof(kcqe_t)) & 0x7f) != (con_idx & 0x7f));
4553eef4f27bSRobert Mustacchi 
4554eef4f27bSRobert Mustacchi     num_cqes = 0;
4555eef4f27bSRobert Mustacchi     prod_idx = pdev->vars.status_virt->deflt.status_completion_producer_index;
4556eef4f27bSRobert Mustacchi 
4557eef4f27bSRobert Mustacchi     while(con_idx != prod_idx && num_cqes != ptr_cnt)
4558eef4f27bSRobert Mustacchi     {
4559eef4f27bSRobert Mustacchi         *cqe_ptr = con_qe;
4560eef4f27bSRobert Mustacchi         cqe_ptr++;
4561eef4f27bSRobert Mustacchi         num_cqes++;
4562eef4f27bSRobert Mustacchi         con_idx++;
4563eef4f27bSRobert Mustacchi 
4564eef4f27bSRobert Mustacchi         if(con_qe == pdev->kq_info.kcq_last_qe)
4565eef4f27bSRobert Mustacchi         {
4566eef4f27bSRobert Mustacchi             con_qe = pdev->kq_info.kcq_virt;
4567eef4f27bSRobert Mustacchi         }
4568eef4f27bSRobert Mustacchi         else
4569eef4f27bSRobert Mustacchi         {
4570eef4f27bSRobert Mustacchi             con_qe++;
4571eef4f27bSRobert Mustacchi         }
4572eef4f27bSRobert Mustacchi 
4573eef4f27bSRobert Mustacchi         prod_idx =
4574eef4f27bSRobert Mustacchi             pdev->vars.status_virt->deflt.status_completion_producer_index;
4575eef4f27bSRobert Mustacchi     }
4576eef4f27bSRobert Mustacchi 
4577eef4f27bSRobert Mustacchi     /* Make sure the last entry in the array does not have the 'next'
4578eef4f27bSRobert Mustacchi      * bit set.  We want to ensure the array contains all the cqes
4579eef4f27bSRobert Mustacchi      * for a completion.
4580eef4f27bSRobert Mustacchi      *
4581eef4f27bSRobert Mustacchi      * This piece of code also takes care of the case where a completion
4582eef4f27bSRobert Mustacchi      * spans multiple kcqes and not all the kcqes have been dma'd to
4583eef4f27bSRobert Mustacchi      * the host.  For example, if a completion consists of A, B, C, and D
4584eef4f27bSRobert Mustacchi      * kcqes.  The status block may tell us A and B have been dma'd.  In
4585eef4f27bSRobert Mustacchi      * this case, we don't want to return kcqes A and B in the array. */
4586eef4f27bSRobert Mustacchi     cqe_ptr--;
4587eef4f27bSRobert Mustacchi     while(num_cqes && ((*cqe_ptr)->kcqe_flags & KCQE_FLAGS_NEXT))
4588eef4f27bSRobert Mustacchi     {
4589eef4f27bSRobert Mustacchi         num_cqes--;
4590eef4f27bSRobert Mustacchi         cqe_ptr--;
4591eef4f27bSRobert Mustacchi     }
4592eef4f27bSRobert Mustacchi 
4593eef4f27bSRobert Mustacchi     DbgBreakIf(num_cqes == 0);
4594eef4f27bSRobert Mustacchi 
4595eef4f27bSRobert Mustacchi     return num_cqes;
4596eef4f27bSRobert Mustacchi } /* lm_get_kernel_cqes */
4597eef4f27bSRobert Mustacchi 
4598eef4f27bSRobert Mustacchi 
4599eef4f27bSRobert Mustacchi 
4600eef4f27bSRobert Mustacchi /*******************************************************************************
4601eef4f27bSRobert Mustacchi  * Description:
4602eef4f27bSRobert Mustacchi  *
4603eef4f27bSRobert Mustacchi  * Return:
4604eef4f27bSRobert Mustacchi  ******************************************************************************/
4605eef4f27bSRobert Mustacchi u8_t
lm_ack_kernel_cqes(lm_device_t * pdev,u32_t num_cqes)4606eef4f27bSRobert Mustacchi lm_ack_kernel_cqes(
4607eef4f27bSRobert Mustacchi     lm_device_t *pdev,
4608eef4f27bSRobert Mustacchi     u32_t num_cqes)
4609eef4f27bSRobert Mustacchi {
4610eef4f27bSRobert Mustacchi     kcqe_t *con_qe;
4611eef4f27bSRobert Mustacchi     u16_t prod_idx;
4612eef4f27bSRobert Mustacchi     u16_t con_idx;
4613eef4f27bSRobert Mustacchi 
4614eef4f27bSRobert Mustacchi     DbgMessage(pdev, VERBOSEint, "### lm_ack_kernel_cqes\n");
4615eef4f27bSRobert Mustacchi 
4616eef4f27bSRobert Mustacchi     con_idx = pdev->kq_info.kcq_con_idx;
4617eef4f27bSRobert Mustacchi 
4618eef4f27bSRobert Mustacchi     if(num_cqes)
4619eef4f27bSRobert Mustacchi     {
4620eef4f27bSRobert Mustacchi         /* Advance the consumer index and the con_qe pointer */
4621eef4f27bSRobert Mustacchi         con_idx += (u16_t) num_cqes;
4622eef4f27bSRobert Mustacchi         con_qe = pdev->kq_info.kcq_con_qe + num_cqes;
4623eef4f27bSRobert Mustacchi 
4624eef4f27bSRobert Mustacchi         /* Check for con_qe wrap around. */
4625eef4f27bSRobert Mustacchi         if((u8_t *) con_qe > (u8_t *) pdev->kq_info.kcq_last_qe)
4626eef4f27bSRobert Mustacchi         {
4627eef4f27bSRobert Mustacchi             con_qe = (kcqe_t *) ((u8_t *) pdev->kq_info.kcq_virt +
4628eef4f27bSRobert Mustacchi                 ((u8_t *) con_qe - (u8_t *) pdev->kq_info.kcq_last_qe));
4629eef4f27bSRobert Mustacchi             con_qe--;
4630eef4f27bSRobert Mustacchi         }
4631eef4f27bSRobert Mustacchi 
4632eef4f27bSRobert Mustacchi         pdev->kq_info.kcq_con_idx = con_idx;
4633eef4f27bSRobert Mustacchi         pdev->kq_info.kcq_con_qe = con_qe;
4634eef4f27bSRobert Mustacchi 
4635eef4f27bSRobert Mustacchi         /* Don't acknowledge the last 'kcq_history_size' entries so the
4636eef4f27bSRobert Mustacchi          * chip will not over write them with new entries.  We are doing
4637eef4f27bSRobert Mustacchi          * this to have a history of the kcq entries for debugging. */
4638eef4f27bSRobert Mustacchi         if(pdev->params.kcq_history_size)
4639eef4f27bSRobert Mustacchi         {
4640eef4f27bSRobert Mustacchi             /* The con_idx should always be ahead of history_kcq_con_idx. */
4641eef4f27bSRobert Mustacchi             DbgBreakIf(S16_SUB(con_idx, pdev->kq_info.history_kcq_con_idx) < 0);
4642eef4f27bSRobert Mustacchi 
4643eef4f27bSRobert Mustacchi             /* Number of entries between con_idx and history_kcq_con_idx. */
4644eef4f27bSRobert Mustacchi             num_cqes = (u32_t) S16_SUB(
4645eef4f27bSRobert Mustacchi                 con_idx,
4646eef4f27bSRobert Mustacchi                 pdev->kq_info.history_kcq_con_idx);
4647eef4f27bSRobert Mustacchi 
4648eef4f27bSRobert Mustacchi             /* Don't advance the consumer index if the number of history
4649eef4f27bSRobert Mustacchi              * entries is less than 'kcq_history_size'. */
4650eef4f27bSRobert Mustacchi             if(num_cqes >= pdev->params.kcq_history_size)
4651eef4f27bSRobert Mustacchi             {
4652eef4f27bSRobert Mustacchi                 /* Make sure we will have at most kcq_history_size entires. */
4653eef4f27bSRobert Mustacchi                 num_cqes -= pdev->params.kcq_history_size;
4654eef4f27bSRobert Mustacchi 
4655eef4f27bSRobert Mustacchi                 DbgBreakIf(num_cqes > pdev->params.kcq_history_size);
4656eef4f27bSRobert Mustacchi 
4657eef4f27bSRobert Mustacchi                 /* Advance the consumer index and the con_qe pointer */
4658eef4f27bSRobert Mustacchi                 pdev->kq_info.history_kcq_con_idx += (u16_t) num_cqes;
4659eef4f27bSRobert Mustacchi                 con_qe = pdev->kq_info.history_kcq_con_qe + num_cqes;
4660eef4f27bSRobert Mustacchi 
4661eef4f27bSRobert Mustacchi                 /* Check for con_qe wrap around. */
4662eef4f27bSRobert Mustacchi                 if((u8_t *) con_qe > (u8_t *) pdev->kq_info.kcq_last_qe)
4663eef4f27bSRobert Mustacchi                 {
4664eef4f27bSRobert Mustacchi                     con_qe = (kcqe_t *) ((u8_t *) pdev->kq_info.kcq_virt +
4665eef4f27bSRobert Mustacchi                         ((u8_t *) con_qe -
4666eef4f27bSRobert Mustacchi                          (u8_t *) pdev->kq_info.kcq_last_qe));
4667eef4f27bSRobert Mustacchi                     con_qe--;
4668eef4f27bSRobert Mustacchi                 }
4669eef4f27bSRobert Mustacchi                 pdev->kq_info.history_kcq_con_qe = con_qe;
4670eef4f27bSRobert Mustacchi 
4671eef4f27bSRobert Mustacchi                 MBQ_WR16(
4672eef4f27bSRobert Mustacchi                     pdev,
4673eef4f27bSRobert Mustacchi                     GET_CID(pdev->kq_info.kcq_cid_addr),
4674eef4f27bSRobert Mustacchi                     OFFSETOF(krnlq_context_t, krnlq_host_qidx),
4675eef4f27bSRobert Mustacchi                     pdev->kq_info.history_kcq_con_idx);
4676eef4f27bSRobert Mustacchi             }
4677eef4f27bSRobert Mustacchi         }
4678eef4f27bSRobert Mustacchi         else
4679eef4f27bSRobert Mustacchi         {
4680eef4f27bSRobert Mustacchi             MBQ_WR16(
4681eef4f27bSRobert Mustacchi                 pdev,
4682eef4f27bSRobert Mustacchi                 GET_CID(pdev->kq_info.kcq_cid_addr),
4683eef4f27bSRobert Mustacchi                 OFFSETOF(krnlq_context_t, krnlq_host_qidx),
4684eef4f27bSRobert Mustacchi                 con_idx);
4685eef4f27bSRobert Mustacchi         }
4686eef4f27bSRobert Mustacchi     }
4687eef4f27bSRobert Mustacchi 
4688eef4f27bSRobert Mustacchi     prod_idx = pdev->vars.status_virt->deflt.status_completion_producer_index;
4689eef4f27bSRobert Mustacchi 
4690eef4f27bSRobert Mustacchi     DbgBreakIf(S16_SUB(prod_idx, con_idx) < 0);
4691eef4f27bSRobert Mustacchi 
4692eef4f27bSRobert Mustacchi     return con_idx != prod_idx;
4693eef4f27bSRobert Mustacchi } /* lm_ack_kernel_cqes */
4694eef4f27bSRobert Mustacchi #endif /* EXCLUDE_KQE_SUPPORT */
4695eef4f27bSRobert Mustacchi 
4696eef4f27bSRobert Mustacchi 
4697eef4f27bSRobert Mustacchi 
4698eef4f27bSRobert Mustacchi #ifndef EXCLUDE_RSS_SUPPORT
4699eef4f27bSRobert Mustacchi #if RSS_LOOKUP_TABLE_WA
4700eef4f27bSRobert Mustacchi /*******************************************************************************
4701eef4f27bSRobert Mustacchi  * Description:
4702eef4f27bSRobert Mustacchi  *
4703eef4f27bSRobert Mustacchi  * Return:
4704eef4f27bSRobert Mustacchi  ******************************************************************************/
4705eef4f27bSRobert Mustacchi u64_t
rss_f64(u8_t * key,u8_t s,u8_t e)4706eef4f27bSRobert Mustacchi rss_f64(
4707eef4f27bSRobert Mustacchi     u8_t* key,
4708eef4f27bSRobert Mustacchi     u8_t s,
4709eef4f27bSRobert Mustacchi     u8_t e
4710eef4f27bSRobert Mustacchi     )
4711eef4f27bSRobert Mustacchi {
4712eef4f27bSRobert Mustacchi     u64_t f;
4713eef4f27bSRobert Mustacchi 
4714eef4f27bSRobert Mustacchi     for( f=0; s<=e; ++s )
4715eef4f27bSRobert Mustacchi     {
4716eef4f27bSRobert Mustacchi         f = (f << 8);
4717eef4f27bSRobert Mustacchi         f |= key[s];
4718eef4f27bSRobert Mustacchi     }
4719eef4f27bSRobert Mustacchi 
4720eef4f27bSRobert Mustacchi     return f;
4721eef4f27bSRobert Mustacchi }
4722eef4f27bSRobert Mustacchi 
4723eef4f27bSRobert Mustacchi 
4724eef4f27bSRobert Mustacchi 
4725eef4f27bSRobert Mustacchi /*******************************************************************************
4726eef4f27bSRobert Mustacchi  * Description:
4727eef4f27bSRobert Mustacchi  *
4728eef4f27bSRobert Mustacchi  * Return:
4729eef4f27bSRobert Mustacchi  ******************************************************************************/
4730eef4f27bSRobert Mustacchi u32_t
rss_hash_byte(u8_t * key,u8_t byte,u8_t s,u8_t e,u32_t rst)4731eef4f27bSRobert Mustacchi rss_hash_byte(
4732eef4f27bSRobert Mustacchi     u8_t* key,
4733eef4f27bSRobert Mustacchi     u8_t  byte,
4734eef4f27bSRobert Mustacchi     u8_t  s,
4735eef4f27bSRobert Mustacchi     u8_t  e,
4736eef4f27bSRobert Mustacchi     u32_t rst
4737eef4f27bSRobert Mustacchi     )
4738eef4f27bSRobert Mustacchi {
4739eef4f27bSRobert Mustacchi     u8_t i;
4740eef4f27bSRobert Mustacchi     u64_t key_msb;
4741eef4f27bSRobert Mustacchi 
4742eef4f27bSRobert Mustacchi     key_msb = rss_f64(key, s,e);
4743eef4f27bSRobert Mustacchi 
4744eef4f27bSRobert Mustacchi     for( i=0x80; i!=0; i>>=1 )
4745eef4f27bSRobert Mustacchi     {
4746eef4f27bSRobert Mustacchi         if( i & byte )
4747eef4f27bSRobert Mustacchi         {
4748eef4f27bSRobert Mustacchi             u32_t k;
4749eef4f27bSRobert Mustacchi 
4750eef4f27bSRobert Mustacchi             k = (u32_t)(key_msb >> 32);
4751eef4f27bSRobert Mustacchi             rst ^= k;
4752eef4f27bSRobert Mustacchi         }
4753eef4f27bSRobert Mustacchi         key_msb = (key_msb << 1);
4754eef4f27bSRobert Mustacchi     }
4755eef4f27bSRobert Mustacchi 
4756eef4f27bSRobert Mustacchi     return rst;
4757eef4f27bSRobert Mustacchi }
4758eef4f27bSRobert Mustacchi 
4759eef4f27bSRobert Mustacchi 
4760eef4f27bSRobert Mustacchi 
4761eef4f27bSRobert Mustacchi /*******************************************************************************
4762eef4f27bSRobert Mustacchi  * Description:
4763eef4f27bSRobert Mustacchi  *
4764eef4f27bSRobert Mustacchi  * Return:
4765eef4f27bSRobert Mustacchi  ******************************************************************************/
4766eef4f27bSRobert Mustacchi void
rss_gen_one_table(u8_t * key,u8_t s,u8_t e,u32_t * gtbl)4767eef4f27bSRobert Mustacchi rss_gen_one_table(
4768eef4f27bSRobert Mustacchi     u8_t* key,
4769eef4f27bSRobert Mustacchi     u8_t  s,
4770eef4f27bSRobert Mustacchi     u8_t  e,
4771eef4f27bSRobert Mustacchi     u32_t* gtbl
4772eef4f27bSRobert Mustacchi     )
4773eef4f27bSRobert Mustacchi {
4774eef4f27bSRobert Mustacchi     u32_t i;
4775eef4f27bSRobert Mustacchi 
4776eef4f27bSRobert Mustacchi     for( i = 0; i < 256; ++i )
4777eef4f27bSRobert Mustacchi     {
4778eef4f27bSRobert Mustacchi         gtbl[i] = rss_hash_byte( key, (u8_t)i, s, e, 0 );
4779eef4f27bSRobert Mustacchi     }
4780eef4f27bSRobert Mustacchi }
4781eef4f27bSRobert Mustacchi 
4782eef4f27bSRobert Mustacchi 
4783eef4f27bSRobert Mustacchi 
4784eef4f27bSRobert Mustacchi /*******************************************************************************
4785eef4f27bSRobert Mustacchi  * Description:
4786eef4f27bSRobert Mustacchi  *
4787eef4f27bSRobert Mustacchi  * Return:
4788eef4f27bSRobert Mustacchi  ******************************************************************************/
4789eef4f27bSRobert Mustacchi void
rss_gen_tables(u8_t * key,u32_t * tables)4790eef4f27bSRobert Mustacchi rss_gen_tables(
4791eef4f27bSRobert Mustacchi     u8_t* key,
4792eef4f27bSRobert Mustacchi     u32_t* tables
4793eef4f27bSRobert Mustacchi     )
4794eef4f27bSRobert Mustacchi {
4795eef4f27bSRobert Mustacchi     u8_t t;
4796eef4f27bSRobert Mustacchi 
4797eef4f27bSRobert Mustacchi     for( t = 0; t < 12; ++t )
4798eef4f27bSRobert Mustacchi     {
4799eef4f27bSRobert Mustacchi         rss_gen_one_table( key, t, (u8_t)(t+7), tables );
4800eef4f27bSRobert Mustacchi         tables += 256;
4801eef4f27bSRobert Mustacchi     }
4802eef4f27bSRobert Mustacchi }
4803eef4f27bSRobert Mustacchi #endif
4804eef4f27bSRobert Mustacchi 
4805eef4f27bSRobert Mustacchi 
4806eef4f27bSRobert Mustacchi #ifndef LM_NON_LEGACY_MODE_SUPPORT
4807eef4f27bSRobert Mustacchi /*******************************************************************************
4808eef4f27bSRobert Mustacchi  * Description:
4809eef4f27bSRobert Mustacchi  *
4810eef4f27bSRobert Mustacchi  * Return:
4811eef4f27bSRobert Mustacchi  ******************************************************************************/
4812eef4f27bSRobert Mustacchi lm_status_t
lm_enable_rss(lm_device_t * pdev,lm_rss_hash_t hash_type,u8_t * indirection_table,u32_t table_size,u8_t * hash_key,u32_t key_size)4813eef4f27bSRobert Mustacchi lm_enable_rss(
4814eef4f27bSRobert Mustacchi     lm_device_t *pdev,
4815eef4f27bSRobert Mustacchi     lm_rss_hash_t hash_type,
4816eef4f27bSRobert Mustacchi     u8_t *indirection_table,
4817eef4f27bSRobert Mustacchi     u32_t table_size,
4818eef4f27bSRobert Mustacchi     u8_t *hash_key,
4819eef4f27bSRobert Mustacchi     u32_t key_size)
4820eef4f27bSRobert Mustacchi {
4821eef4f27bSRobert Mustacchi     l2_kwqe_rss_table_update_t *rss_update;
4822eef4f27bSRobert Mustacchi     u8_t rss_key[RSS_HASH_KEY_SIZE];
4823eef4f27bSRobert Mustacchi     lm_address_t rss_table_phy;
4824eef4f27bSRobert Mustacchi     u8_t *rss_table_virt;
4825eef4f27bSRobert Mustacchi     kwqe_t *prod_qe;
4826eef4f27bSRobert Mustacchi     u16_t prod_idx;
4827eef4f27bSRobert Mustacchi     u32_t idx;
4828eef4f27bSRobert Mustacchi     u32_t val;
4829eef4f27bSRobert Mustacchi 
4830eef4f27bSRobert Mustacchi     if(pdev->kq_info.kwqe_left < 2)
4831eef4f27bSRobert Mustacchi     {
4832eef4f27bSRobert Mustacchi         pdev->kq_info.no_kwq_bd_left++;
4833eef4f27bSRobert Mustacchi         return LM_STATUS_RESOURCE;
4834eef4f27bSRobert Mustacchi     }
4835eef4f27bSRobert Mustacchi 
4836eef4f27bSRobert Mustacchi     pdev->kq_info.kwqe_left -= 2;
4837eef4f27bSRobert Mustacchi 
4838eef4f27bSRobert Mustacchi     DbgBreakIf(key_size > RSS_HASH_KEY_SIZE);
4839eef4f27bSRobert Mustacchi 
4840eef4f27bSRobert Mustacchi     /* Initialize the rss key array. */
4841eef4f27bSRobert Mustacchi     if(key_size > RSS_HASH_KEY_SIZE)
4842eef4f27bSRobert Mustacchi     {
4843eef4f27bSRobert Mustacchi         key_size = RSS_HASH_KEY_SIZE;
4844eef4f27bSRobert Mustacchi     }
4845eef4f27bSRobert Mustacchi 
4846eef4f27bSRobert Mustacchi     for(idx = 0; idx < key_size; idx++)
4847eef4f27bSRobert Mustacchi     {
4848eef4f27bSRobert Mustacchi         rss_key[idx] = hash_key[idx];
4849eef4f27bSRobert Mustacchi     }
4850eef4f27bSRobert Mustacchi 
4851eef4f27bSRobert Mustacchi     for(idx = key_size; idx < RSS_HASH_KEY_SIZE; idx++)
4852eef4f27bSRobert Mustacchi     {
4853eef4f27bSRobert Mustacchi         rss_key[idx] = 0;
4854eef4f27bSRobert Mustacchi     }
4855eef4f27bSRobert Mustacchi 
4856eef4f27bSRobert Mustacchi     DbgBreakIf(table_size > RSS_INDIRECTION_TABLE_SIZE);
4857eef4f27bSRobert Mustacchi 
4858eef4f27bSRobert Mustacchi     if(table_size > RSS_INDIRECTION_TABLE_SIZE)
4859eef4f27bSRobert Mustacchi     {
4860eef4f27bSRobert Mustacchi         table_size = RSS_INDIRECTION_TABLE_SIZE;
4861eef4f27bSRobert Mustacchi     }
4862eef4f27bSRobert Mustacchi 
4863eef4f27bSRobert Mustacchi     if(CHIP_NUM(pdev) == CHIP_NUM_5709)
4864eef4f27bSRobert Mustacchi     {
4865eef4f27bSRobert Mustacchi         REG_RD(pdev, rlup.rlup_rss_config, &val);
4866eef4f27bSRobert Mustacchi         val &= ~RLUP_RSS_CONFIG_IPV4_RSS_TYPE_OFF_XI;
4867eef4f27bSRobert Mustacchi         val &= ~RLUP_RSS_CONFIG_IPV6_RSS_TYPE_OFF_XI;
4868eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_rss_config, val);
4869eef4f27bSRobert Mustacchi 
4870eef4f27bSRobert Mustacchi         val = (rss_key[0] << 24) |
4871eef4f27bSRobert Mustacchi               (rss_key[1] << 16) |
4872eef4f27bSRobert Mustacchi               (rss_key[2] << 8) |
4873eef4f27bSRobert Mustacchi                rss_key[3];
4874eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_rss_key1, val);
4875eef4f27bSRobert Mustacchi 
4876eef4f27bSRobert Mustacchi         val = (rss_key[4] << 24) |
4877eef4f27bSRobert Mustacchi               (rss_key[5] << 16) |
4878eef4f27bSRobert Mustacchi               (rss_key[6] << 8) |
4879eef4f27bSRobert Mustacchi                rss_key[7];
4880eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_rss_key2, val);
4881eef4f27bSRobert Mustacchi 
4882eef4f27bSRobert Mustacchi         val = (rss_key[8] << 24) |
4883eef4f27bSRobert Mustacchi               (rss_key[9] << 16) |
4884eef4f27bSRobert Mustacchi               (rss_key[10] << 8) |
4885eef4f27bSRobert Mustacchi                rss_key[11];
4886eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_rss_key3, val);
4887eef4f27bSRobert Mustacchi 
4888eef4f27bSRobert Mustacchi         val = (rss_key[12] << 24) |
4889eef4f27bSRobert Mustacchi               (rss_key[13] << 16) |
4890eef4f27bSRobert Mustacchi               (rss_key[14] << 8) |
4891eef4f27bSRobert Mustacchi                rss_key[15];
4892eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_rss_key4, val);
4893eef4f27bSRobert Mustacchi 
4894eef4f27bSRobert Mustacchi         val = (rss_key[16] << 24) |
4895eef4f27bSRobert Mustacchi               (rss_key[17] << 16) |
4896eef4f27bSRobert Mustacchi               (rss_key[18] << 8) |
4897eef4f27bSRobert Mustacchi                rss_key[19];
4898eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_ipv6_rss_key5, val);
4899eef4f27bSRobert Mustacchi 
4900eef4f27bSRobert Mustacchi         val = (rss_key[20] << 24) |
4901eef4f27bSRobert Mustacchi               (rss_key[21] << 16) |
4902eef4f27bSRobert Mustacchi               (rss_key[22] << 8) |
4903eef4f27bSRobert Mustacchi                rss_key[23];
4904eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_ipv6_rss_key6, val);
4905eef4f27bSRobert Mustacchi 
4906eef4f27bSRobert Mustacchi         val = (rss_key[24] << 24) |
4907eef4f27bSRobert Mustacchi               (rss_key[25] << 16) |
4908eef4f27bSRobert Mustacchi               (rss_key[26] << 8) |
4909eef4f27bSRobert Mustacchi                rss_key[27];
4910eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_ipv6_rss_key7, val);
4911eef4f27bSRobert Mustacchi 
4912eef4f27bSRobert Mustacchi         val = (rss_key[28] << 24) |
4913eef4f27bSRobert Mustacchi               (rss_key[29] << 16) |
4914eef4f27bSRobert Mustacchi               (rss_key[30] << 8) |
4915eef4f27bSRobert Mustacchi                rss_key[31];
4916eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_ipv6_rss_key8, val);
4917eef4f27bSRobert Mustacchi 
4918eef4f27bSRobert Mustacchi         val = (rss_key[32] << 24) |
4919eef4f27bSRobert Mustacchi               (rss_key[33] << 16) |
4920eef4f27bSRobert Mustacchi               (rss_key[34] << 8) |
4921eef4f27bSRobert Mustacchi                rss_key[35];
4922eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_ipv6_rss_key9, val);
4923eef4f27bSRobert Mustacchi 
4924eef4f27bSRobert Mustacchi         val = (rss_key[36] << 24) |
4925eef4f27bSRobert Mustacchi               (rss_key[37] << 16) |
4926eef4f27bSRobert Mustacchi               (rss_key[38] << 8) |
4927eef4f27bSRobert Mustacchi                rss_key[39];
4928eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_ipv6_rss_key10, val);
4929eef4f27bSRobert Mustacchi     }
4930eef4f27bSRobert Mustacchi 
4931eef4f27bSRobert Mustacchi     rss_table_virt = pdev->rx_info.rss_ind_table_virt;
4932eef4f27bSRobert Mustacchi     rss_table_phy = pdev->rx_info.rss_ind_table_phy;
4933eef4f27bSRobert Mustacchi 
4934eef4f27bSRobert Mustacchi     for(idx = 0; idx < table_size; idx++)
4935eef4f27bSRobert Mustacchi     {
4936eef4f27bSRobert Mustacchi         rss_table_virt[idx] = indirection_table[idx];
4937eef4f27bSRobert Mustacchi     }
4938eef4f27bSRobert Mustacchi 
4939eef4f27bSRobert Mustacchi     prod_qe = pdev->kq_info.kwq_prod_qe;
4940eef4f27bSRobert Mustacchi     prod_idx = pdev->kq_info.kwq_prod_idx;
4941eef4f27bSRobert Mustacchi 
4942eef4f27bSRobert Mustacchi     /* Initialize the RSS update KWQE. */
4943eef4f27bSRobert Mustacchi     rss_update = (l2_kwqe_rss_table_update_t *) prod_qe;
4944eef4f27bSRobert Mustacchi 
4945eef4f27bSRobert Mustacchi     rss_update->rss_flags = L2_KWQE_FLAGS_LAYER_MASK_L2;
4946eef4f27bSRobert Mustacchi     rss_update->rss_opcode = L2_KWQE_OPCODE_VALUE_UPDATE_RSS;
4947eef4f27bSRobert Mustacchi 
4948eef4f27bSRobert Mustacchi     rss_update->rss_table_size = (u16_t) table_size;
4949eef4f27bSRobert Mustacchi     rss_update->rss_table_haddr_lo = rss_table_phy.as_u32.low;
4950eef4f27bSRobert Mustacchi     rss_update->rss_table_haddr_hi = rss_table_phy.as_u32.high;
4951eef4f27bSRobert Mustacchi     rss_update->rss_host_opaque = 0;
4952eef4f27bSRobert Mustacchi     rss_update->rss_hash_type = hash_type;
4953eef4f27bSRobert Mustacchi 
4954eef4f27bSRobert Mustacchi     #if RSS_LOOKUP_TABLE_WA
4955eef4f27bSRobert Mustacchi     rss_table_virt += RSS_INDIRECTION_TABLE_SIZE;
4956eef4f27bSRobert Mustacchi     LM_INC64(&rss_table_phy, RSS_INDIRECTION_TABLE_SIZE);
4957eef4f27bSRobert Mustacchi 
4958eef4f27bSRobert Mustacchi     rss_update->rss_lookup_table_lo = rss_table_phy.as_u32.low;
4959eef4f27bSRobert Mustacchi     rss_update->rss_lookup_table_hi = rss_table_phy.as_u32.high;
4960eef4f27bSRobert Mustacchi 
4961eef4f27bSRobert Mustacchi     rss_gen_tables(rss_key, (u32_t *) rss_table_virt);
4962eef4f27bSRobert Mustacchi     #endif
4963eef4f27bSRobert Mustacchi 
4964eef4f27bSRobert Mustacchi     /* Advance to the next KWQE. */
4965eef4f27bSRobert Mustacchi     if(prod_qe == pdev->kq_info.kwq_last_qe)
4966eef4f27bSRobert Mustacchi     {
4967eef4f27bSRobert Mustacchi         prod_qe = pdev->kq_info.kwq_virt;
4968eef4f27bSRobert Mustacchi     }
4969eef4f27bSRobert Mustacchi     else
4970eef4f27bSRobert Mustacchi     {
4971eef4f27bSRobert Mustacchi         prod_qe++;
4972eef4f27bSRobert Mustacchi     }
4973eef4f27bSRobert Mustacchi     prod_idx++;
4974eef4f27bSRobert Mustacchi 
4975eef4f27bSRobert Mustacchi     /* Initialize the RSS enable KWQE. */
4976eef4f27bSRobert Mustacchi     rss_update = (l2_kwqe_rss_table_update_t *) prod_qe;
4977eef4f27bSRobert Mustacchi 
4978eef4f27bSRobert Mustacchi     rss_update->rss_flags = L2_KWQE_FLAGS_LAYER_MASK_L2;
4979eef4f27bSRobert Mustacchi     rss_update->rss_opcode = L2_KWQE_OPCODE_VALUE_ENABLE_RSS;
4980eef4f27bSRobert Mustacchi     rss_update->rss_host_opaque = 0;
4981eef4f27bSRobert Mustacchi     rss_update->rss_hash_type = hash_type;
4982eef4f27bSRobert Mustacchi 
4983eef4f27bSRobert Mustacchi     /* Advance to the next KWQE. */
4984eef4f27bSRobert Mustacchi     if(prod_qe == pdev->kq_info.kwq_last_qe)
4985eef4f27bSRobert Mustacchi     {
4986eef4f27bSRobert Mustacchi         prod_qe = pdev->kq_info.kwq_virt;
4987eef4f27bSRobert Mustacchi     }
4988eef4f27bSRobert Mustacchi     else
4989eef4f27bSRobert Mustacchi     {
4990eef4f27bSRobert Mustacchi         prod_qe++;
4991eef4f27bSRobert Mustacchi     }
4992eef4f27bSRobert Mustacchi     prod_idx++;
4993eef4f27bSRobert Mustacchi 
4994eef4f27bSRobert Mustacchi     pdev->kq_info.kwq_prod_qe = prod_qe;
4995eef4f27bSRobert Mustacchi     pdev->kq_info.kwq_prod_idx = prod_idx;
4996eef4f27bSRobert Mustacchi 
4997eef4f27bSRobert Mustacchi     MBQ_WR16(
4998eef4f27bSRobert Mustacchi         pdev,
4999eef4f27bSRobert Mustacchi         GET_CID(pdev->kq_info.kwq_cid_addr),
5000eef4f27bSRobert Mustacchi         OFFSETOF(krnlq_context_t, krnlq_host_qidx),
5001eef4f27bSRobert Mustacchi         prod_idx);
5002eef4f27bSRobert Mustacchi 
5003eef4f27bSRobert Mustacchi     return LM_STATUS_SUCCESS;
5004eef4f27bSRobert Mustacchi } /* lm_enable_rss */
5005eef4f27bSRobert Mustacchi #else /* LM_LEAGCY_MODE_SUPPORT */
5006eef4f27bSRobert Mustacchi /*******************************************************************************
5007eef4f27bSRobert Mustacchi  * Description:
5008eef4f27bSRobert Mustacchi  *
5009eef4f27bSRobert Mustacchi  * Return:
5010eef4f27bSRobert Mustacchi  ******************************************************************************/
5011eef4f27bSRobert Mustacchi lm_status_t
lm_enable_rss(lm_device_t * pdev,lm_rss_hash_t hash_type,PROCESSOR_NUMBER * indirection_table,u32_t table_size,u8_t * hash_key,u32_t key_size,u8_t * cpu_tbl,u8_t * rss_qidx_tbl)5012eef4f27bSRobert Mustacchi lm_enable_rss(
5013eef4f27bSRobert Mustacchi     lm_device_t *pdev,
5014eef4f27bSRobert Mustacchi     lm_rss_hash_t hash_type,
5015eef4f27bSRobert Mustacchi     PROCESSOR_NUMBER *indirection_table,
5016eef4f27bSRobert Mustacchi     u32_t table_size,
5017eef4f27bSRobert Mustacchi     u8_t *hash_key,
5018eef4f27bSRobert Mustacchi     u32_t key_size,
5019eef4f27bSRobert Mustacchi     u8_t *cpu_tbl,
5020eef4f27bSRobert Mustacchi     u8_t *rss_qidx_tbl)
5021eef4f27bSRobert Mustacchi {
5022eef4f27bSRobert Mustacchi     l2_kwqe_rss_table_update_t *rss_update;
5023eef4f27bSRobert Mustacchi     u8_t rss_key[RSS_HASH_KEY_SIZE];
5024eef4f27bSRobert Mustacchi     lm_address_t rss_table_phy;
5025eef4f27bSRobert Mustacchi     u8_t *rss_table_virt;
5026eef4f27bSRobert Mustacchi     kwqe_t *prod_qe;
5027eef4f27bSRobert Mustacchi     u16_t prod_idx;
5028eef4f27bSRobert Mustacchi     u32_t idx;
5029eef4f27bSRobert Mustacchi     u32_t val;
5030eef4f27bSRobert Mustacchi 
5031eef4f27bSRobert Mustacchi     if(pdev->kq_info.kwqe_left < 2)
5032eef4f27bSRobert Mustacchi     {
5033eef4f27bSRobert Mustacchi         pdev->kq_info.no_kwq_bd_left++;
5034eef4f27bSRobert Mustacchi         return LM_STATUS_RESOURCE;
5035eef4f27bSRobert Mustacchi     }
5036eef4f27bSRobert Mustacchi 
5037eef4f27bSRobert Mustacchi     pdev->kq_info.kwqe_left -= 2;
5038eef4f27bSRobert Mustacchi 
5039eef4f27bSRobert Mustacchi     DbgBreakIf(key_size > RSS_HASH_KEY_SIZE);
5040eef4f27bSRobert Mustacchi 
5041eef4f27bSRobert Mustacchi     /* Initialize the rss key array. */
5042eef4f27bSRobert Mustacchi     if(key_size > RSS_HASH_KEY_SIZE)
5043eef4f27bSRobert Mustacchi     {
5044eef4f27bSRobert Mustacchi         key_size = RSS_HASH_KEY_SIZE;
5045eef4f27bSRobert Mustacchi     }
5046eef4f27bSRobert Mustacchi 
5047eef4f27bSRobert Mustacchi     for(idx = 0; idx < key_size; idx++)
5048eef4f27bSRobert Mustacchi     {
5049eef4f27bSRobert Mustacchi         rss_key[idx] = hash_key[idx];
5050eef4f27bSRobert Mustacchi     }
5051eef4f27bSRobert Mustacchi 
5052eef4f27bSRobert Mustacchi     for(idx = key_size; idx < RSS_HASH_KEY_SIZE; idx++)
5053eef4f27bSRobert Mustacchi     {
5054eef4f27bSRobert Mustacchi         rss_key[idx] = 0;
5055eef4f27bSRobert Mustacchi     }
5056eef4f27bSRobert Mustacchi 
5057eef4f27bSRobert Mustacchi     DbgBreakIf(table_size > RSS_INDIRECTION_TABLE_SIZE);
5058eef4f27bSRobert Mustacchi 
5059eef4f27bSRobert Mustacchi     if(table_size > RSS_INDIRECTION_TABLE_SIZE)
5060eef4f27bSRobert Mustacchi     {
5061eef4f27bSRobert Mustacchi         table_size = RSS_INDIRECTION_TABLE_SIZE;
5062eef4f27bSRobert Mustacchi     }
5063eef4f27bSRobert Mustacchi 
5064eef4f27bSRobert Mustacchi     if(CHIP_NUM(pdev) == CHIP_NUM_5709)
5065eef4f27bSRobert Mustacchi     {
5066eef4f27bSRobert Mustacchi         REG_RD(pdev, rlup.rlup_rss_config, &val);
5067eef4f27bSRobert Mustacchi         val &= ~RLUP_RSS_CONFIG_IPV4_RSS_TYPE_OFF_XI;
5068eef4f27bSRobert Mustacchi         val &= ~RLUP_RSS_CONFIG_IPV6_RSS_TYPE_OFF_XI;
5069eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_rss_config, val);
5070eef4f27bSRobert Mustacchi 
5071eef4f27bSRobert Mustacchi         val = (rss_key[0] << 24) |
5072eef4f27bSRobert Mustacchi               (rss_key[1] << 16) |
5073eef4f27bSRobert Mustacchi               (rss_key[2] << 8) |
5074eef4f27bSRobert Mustacchi                rss_key[3];
5075eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_rss_key1, val);
5076eef4f27bSRobert Mustacchi 
5077eef4f27bSRobert Mustacchi         val = (rss_key[4] << 24) |
5078eef4f27bSRobert Mustacchi               (rss_key[5] << 16) |
5079eef4f27bSRobert Mustacchi               (rss_key[6] << 8) |
5080eef4f27bSRobert Mustacchi                rss_key[7];
5081eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_rss_key2, val);
5082eef4f27bSRobert Mustacchi 
5083eef4f27bSRobert Mustacchi         val = (rss_key[8] << 24) |
5084eef4f27bSRobert Mustacchi               (rss_key[9] << 16) |
5085eef4f27bSRobert Mustacchi               (rss_key[10] << 8) |
5086eef4f27bSRobert Mustacchi                rss_key[11];
5087eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_rss_key3, val);
5088eef4f27bSRobert Mustacchi 
5089eef4f27bSRobert Mustacchi         val = (rss_key[12] << 24) |
5090eef4f27bSRobert Mustacchi               (rss_key[13] << 16) |
5091eef4f27bSRobert Mustacchi               (rss_key[14] << 8) |
5092eef4f27bSRobert Mustacchi                rss_key[15];
5093eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_rss_key4, val);
5094eef4f27bSRobert Mustacchi 
5095eef4f27bSRobert Mustacchi         val = (rss_key[16] << 24) |
5096eef4f27bSRobert Mustacchi               (rss_key[17] << 16) |
5097eef4f27bSRobert Mustacchi               (rss_key[18] << 8) |
5098eef4f27bSRobert Mustacchi                rss_key[19];
5099eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_ipv6_rss_key5, val);
5100eef4f27bSRobert Mustacchi 
5101eef4f27bSRobert Mustacchi         val = (rss_key[20] << 24) |
5102eef4f27bSRobert Mustacchi               (rss_key[21] << 16) |
5103eef4f27bSRobert Mustacchi               (rss_key[22] << 8) |
5104eef4f27bSRobert Mustacchi                rss_key[23];
5105eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_ipv6_rss_key6, val);
5106eef4f27bSRobert Mustacchi 
5107eef4f27bSRobert Mustacchi         val = (rss_key[24] << 24) |
5108eef4f27bSRobert Mustacchi               (rss_key[25] << 16) |
5109eef4f27bSRobert Mustacchi               (rss_key[26] << 8) |
5110eef4f27bSRobert Mustacchi                rss_key[27];
5111eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_ipv6_rss_key7, val);
5112eef4f27bSRobert Mustacchi 
5113eef4f27bSRobert Mustacchi         val = (rss_key[28] << 24) |
5114eef4f27bSRobert Mustacchi               (rss_key[29] << 16) |
5115eef4f27bSRobert Mustacchi               (rss_key[30] << 8) |
5116eef4f27bSRobert Mustacchi                rss_key[31];
5117eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_ipv6_rss_key8, val);
5118eef4f27bSRobert Mustacchi 
5119eef4f27bSRobert Mustacchi         val = (rss_key[32] << 24) |
5120eef4f27bSRobert Mustacchi               (rss_key[33] << 16) |
5121eef4f27bSRobert Mustacchi               (rss_key[34] << 8) |
5122eef4f27bSRobert Mustacchi                rss_key[35];
5123eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_ipv6_rss_key9, val);
5124eef4f27bSRobert Mustacchi 
5125eef4f27bSRobert Mustacchi         val = (rss_key[36] << 24) |
5126eef4f27bSRobert Mustacchi               (rss_key[37] << 16) |
5127eef4f27bSRobert Mustacchi               (rss_key[38] << 8) |
5128eef4f27bSRobert Mustacchi                rss_key[39];
5129eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_ipv6_rss_key10, val);
5130eef4f27bSRobert Mustacchi     }
5131eef4f27bSRobert Mustacchi 
5132eef4f27bSRobert Mustacchi     rss_table_virt = pdev->rx_info.rss_ind_table_virt;
5133eef4f27bSRobert Mustacchi     rss_table_phy = pdev->rx_info.rss_ind_table_phy;
5134eef4f27bSRobert Mustacchi 
5135eef4f27bSRobert Mustacchi     pdev->rx_info.rss_tbl_size = table_size;
5136eef4f27bSRobert Mustacchi     if(!cpu_tbl) /* indirection table already had queue idx? */
5137eef4f27bSRobert Mustacchi     {
5138eef4f27bSRobert Mustacchi         for(idx = 0; idx < table_size; idx++)
5139eef4f27bSRobert Mustacchi             rss_table_virt[idx] = indirection_table[idx].Number;
5140eef4f27bSRobert Mustacchi     }
5141eef4f27bSRobert Mustacchi     else
5142eef4f27bSRobert Mustacchi     {
5143eef4f27bSRobert Mustacchi         /* map the cpu num in the indirection table to queue idx
5144eef4f27bSRobert Mustacchi          * according to the cpu table passed down from the um, then
5145eef4f27bSRobert Mustacchi          * rebuilt the table with queue idx*/
5146eef4f27bSRobert Mustacchi         u8_t *rss_cpu_tbl = &cpu_tbl[1];
5147eef4f27bSRobert Mustacchi 
5148eef4f27bSRobert Mustacchi         for(idx = 0; idx < table_size; idx++)
5149eef4f27bSRobert Mustacchi         {
5150eef4f27bSRobert Mustacchi             for(val = 0; val < cpu_tbl[0]; val++)
5151eef4f27bSRobert Mustacchi             {
5152eef4f27bSRobert Mustacchi                 if(indirection_table[idx].Number == rss_cpu_tbl[val])
5153eef4f27bSRobert Mustacchi                 {
5154eef4f27bSRobert Mustacchi                     if(pdev->vars.interrupt_mode == IRQ_MODE_MSIX_BASED ||
5155eef4f27bSRobert Mustacchi                        pdev->vars.interrupt_mode == IRQ_MODE_MSI_BASED)
5156eef4f27bSRobert Mustacchi                     {
5157eef4f27bSRobert Mustacchi                         rss_table_virt[idx] = rss_qidx_tbl[rss_cpu_tbl[val] + 1];
5158eef4f27bSRobert Mustacchi                     }
5159eef4f27bSRobert Mustacchi                     else
5160eef4f27bSRobert Mustacchi                     {
5161eef4f27bSRobert Mustacchi                         rss_table_virt[idx] = (u8_t)val;
5162eef4f27bSRobert Mustacchi                     }
5163eef4f27bSRobert Mustacchi                     break;
5164eef4f27bSRobert Mustacchi                 }
5165eef4f27bSRobert Mustacchi             }
5166eef4f27bSRobert Mustacchi         }
5167eef4f27bSRobert Mustacchi     }
5168eef4f27bSRobert Mustacchi 
5169eef4f27bSRobert Mustacchi     prod_qe = pdev->kq_info.kwq_prod_qe;
5170eef4f27bSRobert Mustacchi     prod_idx = pdev->kq_info.kwq_prod_idx;
5171eef4f27bSRobert Mustacchi 
5172eef4f27bSRobert Mustacchi     /* Initialize the RSS update KWQE. */
5173eef4f27bSRobert Mustacchi     rss_update = (l2_kwqe_rss_table_update_t *) prod_qe;
5174eef4f27bSRobert Mustacchi 
5175eef4f27bSRobert Mustacchi     rss_update->rss_flags = L2_KWQE_FLAGS_LAYER_MASK_L2;
5176eef4f27bSRobert Mustacchi     rss_update->rss_opcode = L2_KWQE_OPCODE_VALUE_UPDATE_RSS;
5177eef4f27bSRobert Mustacchi 
5178eef4f27bSRobert Mustacchi     rss_update->rss_table_size = (u16_t) table_size;
5179eef4f27bSRobert Mustacchi     rss_update->rss_table_haddr_lo = rss_table_phy.as_u32.low;
5180eef4f27bSRobert Mustacchi     rss_update->rss_table_haddr_hi = rss_table_phy.as_u32.high;
5181eef4f27bSRobert Mustacchi     rss_update->rss_host_opaque = 0;
5182eef4f27bSRobert Mustacchi     rss_update->rss_hash_type = hash_type;
5183eef4f27bSRobert Mustacchi 
5184eef4f27bSRobert Mustacchi     #if RSS_LOOKUP_TABLE_WA
5185eef4f27bSRobert Mustacchi     rss_table_virt += RSS_INDIRECTION_TABLE_SIZE;
5186eef4f27bSRobert Mustacchi     LM_INC64(&rss_table_phy, RSS_INDIRECTION_TABLE_SIZE);
5187eef4f27bSRobert Mustacchi 
5188eef4f27bSRobert Mustacchi     rss_update->rss_lookup_table_lo = rss_table_phy.as_u32.low;
5189eef4f27bSRobert Mustacchi     rss_update->rss_lookup_table_hi = rss_table_phy.as_u32.high;
5190eef4f27bSRobert Mustacchi 
5191eef4f27bSRobert Mustacchi     rss_gen_tables(rss_key, (u32_t *) rss_table_virt);
5192eef4f27bSRobert Mustacchi     #endif
5193eef4f27bSRobert Mustacchi 
5194eef4f27bSRobert Mustacchi     /* Advance to the next KWQE. */
5195eef4f27bSRobert Mustacchi     if(prod_qe == pdev->kq_info.kwq_last_qe)
5196eef4f27bSRobert Mustacchi     {
5197eef4f27bSRobert Mustacchi         prod_qe = pdev->kq_info.kwq_virt;
5198eef4f27bSRobert Mustacchi     }
5199eef4f27bSRobert Mustacchi     else
5200eef4f27bSRobert Mustacchi     {
5201eef4f27bSRobert Mustacchi         prod_qe++;
5202eef4f27bSRobert Mustacchi     }
5203eef4f27bSRobert Mustacchi     prod_idx++;
5204eef4f27bSRobert Mustacchi 
5205eef4f27bSRobert Mustacchi     /* Initialize the RSS enable KWQE. */
5206eef4f27bSRobert Mustacchi     rss_update = (l2_kwqe_rss_table_update_t *) prod_qe;
5207eef4f27bSRobert Mustacchi 
5208eef4f27bSRobert Mustacchi     rss_update->rss_flags = L2_KWQE_FLAGS_LAYER_MASK_L2;
5209eef4f27bSRobert Mustacchi     rss_update->rss_opcode = L2_KWQE_OPCODE_VALUE_ENABLE_RSS;
5210eef4f27bSRobert Mustacchi     rss_update->rss_host_opaque = 0;
5211eef4f27bSRobert Mustacchi     rss_update->rss_hash_type = hash_type;
5212eef4f27bSRobert Mustacchi 
5213eef4f27bSRobert Mustacchi     /* Advance to the next KWQE. */
5214eef4f27bSRobert Mustacchi     if(prod_qe == pdev->kq_info.kwq_last_qe)
5215eef4f27bSRobert Mustacchi     {
5216eef4f27bSRobert Mustacchi         prod_qe = pdev->kq_info.kwq_virt;
5217eef4f27bSRobert Mustacchi     }
5218eef4f27bSRobert Mustacchi     else
5219eef4f27bSRobert Mustacchi     {
5220eef4f27bSRobert Mustacchi         prod_qe++;
5221eef4f27bSRobert Mustacchi     }
5222eef4f27bSRobert Mustacchi     prod_idx++;
5223eef4f27bSRobert Mustacchi 
5224eef4f27bSRobert Mustacchi     pdev->kq_info.kwq_prod_qe = prod_qe;
5225eef4f27bSRobert Mustacchi     pdev->kq_info.kwq_prod_idx = prod_idx;
5226eef4f27bSRobert Mustacchi 
5227eef4f27bSRobert Mustacchi     MBQ_WR16(
5228eef4f27bSRobert Mustacchi         pdev,
5229eef4f27bSRobert Mustacchi         GET_CID(pdev->kq_info.kwq_cid_addr),
5230eef4f27bSRobert Mustacchi         OFFSETOF(krnlq_context_t, krnlq_host_qidx),
5231eef4f27bSRobert Mustacchi         prod_idx);
5232eef4f27bSRobert Mustacchi 
5233eef4f27bSRobert Mustacchi     return LM_STATUS_SUCCESS;
5234eef4f27bSRobert Mustacchi } /* lm_enable_rss */
5235eef4f27bSRobert Mustacchi #endif /* LM_NON_LEGACY_MODE_SUPPORT */
5236eef4f27bSRobert Mustacchi 
5237eef4f27bSRobert Mustacchi 
5238eef4f27bSRobert Mustacchi /*******************************************************************************
5239eef4f27bSRobert Mustacchi  * Description:
5240eef4f27bSRobert Mustacchi  *
5241eef4f27bSRobert Mustacchi  * Return:
5242eef4f27bSRobert Mustacchi  ******************************************************************************/
5243eef4f27bSRobert Mustacchi lm_status_t
lm_disable_rss(lm_device_t * pdev)5244eef4f27bSRobert Mustacchi lm_disable_rss(
5245eef4f27bSRobert Mustacchi     lm_device_t *pdev)
5246eef4f27bSRobert Mustacchi {
5247eef4f27bSRobert Mustacchi     l2_kwqe_rss_table_update_t *rss_update;
5248eef4f27bSRobert Mustacchi     kwqe_t *prod_qe;
5249eef4f27bSRobert Mustacchi     u16_t prod_idx;
5250eef4f27bSRobert Mustacchi     u32_t val;
5251eef4f27bSRobert Mustacchi 
5252eef4f27bSRobert Mustacchi     if(pdev->kq_info.kwqe_left < 1)
5253eef4f27bSRobert Mustacchi     {
5254eef4f27bSRobert Mustacchi         pdev->kq_info.no_kwq_bd_left++;
5255eef4f27bSRobert Mustacchi         return LM_STATUS_RESOURCE;
5256eef4f27bSRobert Mustacchi     }
5257eef4f27bSRobert Mustacchi 
5258eef4f27bSRobert Mustacchi     pdev->kq_info.kwqe_left -= 1;
5259eef4f27bSRobert Mustacchi 
5260eef4f27bSRobert Mustacchi     if(CHIP_NUM(pdev) == CHIP_NUM_5709)
5261eef4f27bSRobert Mustacchi     {
5262eef4f27bSRobert Mustacchi         REG_RD(pdev, rlup.rlup_rss_config, &val);
5263eef4f27bSRobert Mustacchi         val &= ~RLUP_RSS_CONFIG_IPV4_RSS_TYPE_OFF_XI;
5264eef4f27bSRobert Mustacchi         val &= ~RLUP_RSS_CONFIG_IPV6_RSS_TYPE_OFF_XI;
5265eef4f27bSRobert Mustacchi         REG_WR(pdev, rlup.rlup_rss_config, val);
5266eef4f27bSRobert Mustacchi     }
5267eef4f27bSRobert Mustacchi 
5268eef4f27bSRobert Mustacchi     prod_qe = pdev->kq_info.kwq_prod_qe;
5269eef4f27bSRobert Mustacchi     prod_idx = pdev->kq_info.kwq_prod_idx;
5270eef4f27bSRobert Mustacchi 
5271eef4f27bSRobert Mustacchi     /* Initialize the RSS enable KWQE. */
5272eef4f27bSRobert Mustacchi     rss_update = (l2_kwqe_rss_table_update_t *) prod_qe;
5273eef4f27bSRobert Mustacchi 
5274eef4f27bSRobert Mustacchi     rss_update->rss_flags = L2_KWQE_FLAGS_LAYER_MASK_L2;
5275eef4f27bSRobert Mustacchi     rss_update->rss_opcode = L2_KWQE_OPCODE_VALUE_DISABLE_RSS;
5276eef4f27bSRobert Mustacchi 
5277eef4f27bSRobert Mustacchi     /* Advance to the next KWQE. */
5278eef4f27bSRobert Mustacchi     if(prod_qe == pdev->kq_info.kwq_last_qe)
5279eef4f27bSRobert Mustacchi     {
5280eef4f27bSRobert Mustacchi         prod_qe = pdev->kq_info.kwq_virt;
5281eef4f27bSRobert Mustacchi     }
5282eef4f27bSRobert Mustacchi     else
5283eef4f27bSRobert Mustacchi     {
5284eef4f27bSRobert Mustacchi         prod_qe++;
5285eef4f27bSRobert Mustacchi     }
5286eef4f27bSRobert Mustacchi     prod_idx++;
5287eef4f27bSRobert Mustacchi 
5288eef4f27bSRobert Mustacchi     pdev->kq_info.kwq_prod_qe = prod_qe;
5289eef4f27bSRobert Mustacchi     pdev->kq_info.kwq_prod_idx = prod_idx;
5290eef4f27bSRobert Mustacchi 
5291eef4f27bSRobert Mustacchi     MBQ_WR16(
5292eef4f27bSRobert Mustacchi         pdev,
5293eef4f27bSRobert Mustacchi         GET_CID(pdev->kq_info.kwq_cid_addr),
5294eef4f27bSRobert Mustacchi         OFFSETOF(krnlq_context_t, krnlq_host_qidx),
5295eef4f27bSRobert Mustacchi         prod_idx);
5296eef4f27bSRobert Mustacchi 
5297eef4f27bSRobert Mustacchi     return LM_STATUS_SUCCESS;
5298eef4f27bSRobert Mustacchi } /* lm_disable_rss */
5299eef4f27bSRobert Mustacchi #endif /* EXCLUDE_RSS_SUPPORT */
5300eef4f27bSRobert Mustacchi 
5301eef4f27bSRobert Mustacchi /*******************************************************************************
5302eef4f27bSRobert Mustacchi  * Description:
5303eef4f27bSRobert Mustacchi  *
5304eef4f27bSRobert Mustacchi  * Return:
5305eef4f27bSRobert Mustacchi  ******************************************************************************/
lm_set_pcie_nfe_report(lm_device_t * pdev)5306eef4f27bSRobert Mustacchi void lm_set_pcie_nfe_report(lm_device_t *pdev)
5307eef4f27bSRobert Mustacchi {
5308eef4f27bSRobert Mustacchi     if(CHIP_NUM(pdev) == CHIP_NUM_5709 &&
5309eef4f27bSRobert Mustacchi        pdev->params.disable_pcie_nfr)
5310eef4f27bSRobert Mustacchi     {
5311eef4f27bSRobert Mustacchi         u16_t pci_devctl;
5312eef4f27bSRobert Mustacchi         REG_RD(pdev,pci_config.pcicfg_device_control,&pci_devctl);
5313eef4f27bSRobert Mustacchi         pci_devctl &= ~PCICFG_DEVICE_CONTROL_NON_FATAL_REP_ENA;
5314eef4f27bSRobert Mustacchi         REG_WR(pdev,pci_config.pcicfg_device_control,pci_devctl);
5315*55fea89dSDan Cross     }
5316eef4f27bSRobert Mustacchi }
5317eef4f27bSRobert Mustacchi 
5318eef4f27bSRobert Mustacchi /*******************************************************************************
5319eef4f27bSRobert Mustacchi  * Description:
5320eef4f27bSRobert Mustacchi  *
5321eef4f27bSRobert Mustacchi  * Return:
5322eef4f27bSRobert Mustacchi  ******************************************************************************/
lm_clear_coalescing_ticks(lm_device_t * pdev)5323eef4f27bSRobert Mustacchi void lm_clear_coalescing_ticks(lm_device_t *pdev)
5324eef4f27bSRobert Mustacchi {
5325eef4f27bSRobert Mustacchi     pdev->params.tx_quick_cons_trip = 1;
5326eef4f27bSRobert Mustacchi     pdev->params.tx_quick_cons_trip_int = 1;
5327eef4f27bSRobert Mustacchi     pdev->params.rx_quick_cons_trip = 1;
5328eef4f27bSRobert Mustacchi     pdev->params.rx_quick_cons_trip_int = 1;
5329eef4f27bSRobert Mustacchi     pdev->params.comp_prod_trip = 1;
5330eef4f27bSRobert Mustacchi     pdev->params.comp_prod_trip_int = 1;
5331eef4f27bSRobert Mustacchi 
5332eef4f27bSRobert Mustacchi     pdev->params.tx_ticks = 0;
5333eef4f27bSRobert Mustacchi     pdev->params.tx_ticks_int = 0;
5334eef4f27bSRobert Mustacchi     pdev->params.com_ticks = 0;
5335eef4f27bSRobert Mustacchi     pdev->params.com_ticks_int = 0;
5336eef4f27bSRobert Mustacchi     pdev->params.cmd_ticks = 0;
5337eef4f27bSRobert Mustacchi     pdev->params.cmd_ticks_int = 0;
5338eef4f27bSRobert Mustacchi     pdev->params.rx_ticks = 0;
5339eef4f27bSRobert Mustacchi     pdev->params.rx_ticks_int = 0;
5340eef4f27bSRobert Mustacchi     pdev->params.stats_ticks = 0;
5341*55fea89dSDan Cross 
5342eef4f27bSRobert Mustacchi     /* Xinan per-processor HC configuration. */
5343eef4f27bSRobert Mustacchi     pdev->params.psb_tx_cons_trip = 0x10001;
5344eef4f27bSRobert Mustacchi     pdev->params.psb_rx_cons_trip = 0x10001;
5345eef4f27bSRobert Mustacchi     pdev->params.psb_comp_prod_trip = 0x10001;
5346*55fea89dSDan Cross 
5347eef4f27bSRobert Mustacchi     pdev->params.psb_tx_ticks = 0;
5348eef4f27bSRobert Mustacchi     pdev->params.psb_rx_ticks = 0;
5349eef4f27bSRobert Mustacchi     pdev->params.psb_com_ticks = 0;
5350eef4f27bSRobert Mustacchi     pdev->params.psb_cmd_ticks = 0;
5351eef4f27bSRobert Mustacchi     pdev->params.psb_period_ticks = 0;
5352eef4f27bSRobert Mustacchi }
5353eef4f27bSRobert Mustacchi 
lm_is_mmio_ok(lm_device_t * pdev)5354eef4f27bSRobert Mustacchi u8_t lm_is_mmio_ok(lm_device_t *pdev)
5355eef4f27bSRobert Mustacchi {
5356eef4f27bSRobert Mustacchi     u32_t val;
5357eef4f27bSRobert Mustacchi     REG_RD(pdev, pci_config.pcicfg_vendor_id, &val);
5358eef4f27bSRobert Mustacchi     if (0xffffffff == val)
5359eef4f27bSRobert Mustacchi     {
5360eef4f27bSRobert Mustacchi         return FALSE;
5361eef4f27bSRobert Mustacchi     }
5362eef4f27bSRobert Mustacchi     else
5363eef4f27bSRobert Mustacchi     {
5364eef4f27bSRobert Mustacchi         return TRUE;
5365eef4f27bSRobert Mustacchi     }
5366eef4f27bSRobert Mustacchi }
5367eef4f27bSRobert Mustacchi 
5368eef4f27bSRobert Mustacchi #if defined(LM_NON_LEGACY_MODE_SUPPORT)
5369eef4f27bSRobert Mustacchi /*******************************************************************************
5370eef4f27bSRobert Mustacchi  * Description:
5371eef4f27bSRobert Mustacchi  *
5372eef4f27bSRobert Mustacchi  * Return:
5373eef4f27bSRobert Mustacchi  ******************************************************************************/
5374*55fea89dSDan Cross void
lm_create_q_group(lm_device_t * pdev,u32_t q_group_id,u32_t lookahead_sz)5375eef4f27bSRobert Mustacchi lm_create_q_group(
5376eef4f27bSRobert Mustacchi     lm_device_t *pdev,
5377eef4f27bSRobert Mustacchi     u32_t q_group_id,
5378eef4f27bSRobert Mustacchi     u32_t lookahead_sz
5379eef4f27bSRobert Mustacchi     )
5380eef4f27bSRobert Mustacchi {
5381eef4f27bSRobert Mustacchi     u32_t val;
5382eef4f27bSRobert Mustacchi     lm_rx_chain_t *rxq;
5383*55fea89dSDan Cross 
5384eef4f27bSRobert Mustacchi     rxq = &pdev->rx_info.chain[q_group_id];
5385eef4f27bSRobert Mustacchi     rxq->vmq_lookahead_size = lookahead_sz;
5386eef4f27bSRobert Mustacchi 
5387eef4f27bSRobert Mustacchi     val = lookahead_sz << 16;
5388eef4f27bSRobert Mustacchi     CTX_WR(
5389eef4f27bSRobert Mustacchi         pdev,
5390eef4f27bSRobert Mustacchi         rxq->cid_addr,
5391eef4f27bSRobert Mustacchi         WORD_ALIGNED_OFFSETOF(l2_bd_chain_context_t,
5392eef4f27bSRobert Mustacchi                               l2ctx_vmq_lookahead_sz),
5393eef4f27bSRobert Mustacchi         val);
5394eef4f27bSRobert Mustacchi }
5395eef4f27bSRobert Mustacchi 
5396eef4f27bSRobert Mustacchi /*******************************************************************************
5397eef4f27bSRobert Mustacchi  * Description:
5398eef4f27bSRobert Mustacchi  *
5399eef4f27bSRobert Mustacchi  * Return:
5400eef4f27bSRobert Mustacchi  ******************************************************************************/
5401*55fea89dSDan Cross lm_status_t
lm_destroy_q_group(lm_device_t * pdev,u32_t q_group_id,u32_t num_queues)5402eef4f27bSRobert Mustacchi lm_destroy_q_group(
5403eef4f27bSRobert Mustacchi     lm_device_t *pdev,
5404eef4f27bSRobert Mustacchi     u32_t q_group_id,
5405eef4f27bSRobert Mustacchi     u32_t num_queues
5406eef4f27bSRobert Mustacchi     )
5407eef4f27bSRobert Mustacchi {
5408eef4f27bSRobert Mustacchi     u32_t num_kwqes_needed;
5409eef4f27bSRobert Mustacchi     kwqe_t *prod_qe;
5410eef4f27bSRobert Mustacchi     u16_t prod_idx;
5411eef4f27bSRobert Mustacchi     l2_kwqe_vm_free_rx_queue_t *kwqe_free_rxq;
5412*55fea89dSDan Cross 
5413eef4f27bSRobert Mustacchi     num_kwqes_needed = num_queues;
5414*55fea89dSDan Cross 
5415eef4f27bSRobert Mustacchi     if(pdev->kq_info.kwqe_left < num_kwqes_needed)
5416eef4f27bSRobert Mustacchi     {
5417eef4f27bSRobert Mustacchi         DbgMessage(pdev, WARN, "No more KWQE left.\n");
5418eef4f27bSRobert Mustacchi 
5419eef4f27bSRobert Mustacchi         pdev->kq_info.no_kwq_bd_left++;
5420eef4f27bSRobert Mustacchi 
5421eef4f27bSRobert Mustacchi         return LM_STATUS_RESOURCE;
5422eef4f27bSRobert Mustacchi     }
5423eef4f27bSRobert Mustacchi 
5424eef4f27bSRobert Mustacchi     prod_qe = pdev->kq_info.kwq_prod_qe;
5425eef4f27bSRobert Mustacchi     prod_idx = pdev->kq_info.kwq_prod_idx;
5426eef4f27bSRobert Mustacchi 
5427eef4f27bSRobert Mustacchi     kwqe_free_rxq = (l2_kwqe_vm_free_rx_queue_t *) prod_qe;
5428*55fea89dSDan Cross 
5429eef4f27bSRobert Mustacchi     if(q_group_id <= RX_CHAIN_IDX3)
5430eef4f27bSRobert Mustacchi     {
5431eef4f27bSRobert Mustacchi         if(q_group_id == RX_CHAIN_IDX0)
5432eef4f27bSRobert Mustacchi         {
5433eef4f27bSRobert Mustacchi             u8_t idx;
5434eef4f27bSRobert Mustacchi             /* default queue may have more than 1 queue pairs */
5435eef4f27bSRobert Mustacchi             for(idx = 0; idx < num_queues; idx++)
5436eef4f27bSRobert Mustacchi             {
5437eef4f27bSRobert Mustacchi                 kwqe_free_rxq->flags = L2_KWQE_FLAGS_LAYER_MASK_L2;
5438eef4f27bSRobert Mustacchi                 kwqe_free_rxq->queue_type = L2_NORMAL_QUEUE;
5439*55fea89dSDan Cross 
5440eef4f27bSRobert Mustacchi                 if(idx == 0)
5441eef4f27bSRobert Mustacchi                     kwqe_free_rxq->qid = (u8_t)q_group_id;
5442eef4f27bSRobert Mustacchi                 else
5443eef4f27bSRobert Mustacchi                 {
5444eef4f27bSRobert Mustacchi                     kwqe_free_rxq->qid = idx + 3;
5445eef4f27bSRobert Mustacchi                 }
5446eef4f27bSRobert Mustacchi 
5447*55fea89dSDan Cross                 kwqe_free_rxq->opcode = L2_KWQE_OPCODE_VALUE_VM_FREE_RX_QUEUE;
5448*55fea89dSDan Cross 
5449eef4f27bSRobert Mustacchi                 /* Advance to the next KWQE. */
5450eef4f27bSRobert Mustacchi                 if(prod_qe == pdev->kq_info.kwq_last_qe)
5451eef4f27bSRobert Mustacchi                 {
5452eef4f27bSRobert Mustacchi                     prod_qe = pdev->kq_info.kwq_virt;
5453eef4f27bSRobert Mustacchi                 }
5454eef4f27bSRobert Mustacchi                 else
5455eef4f27bSRobert Mustacchi                 {
5456eef4f27bSRobert Mustacchi                     prod_qe++;
5457eef4f27bSRobert Mustacchi                 }
5458eef4f27bSRobert Mustacchi                 prod_idx++;
5459eef4f27bSRobert Mustacchi 
5460eef4f27bSRobert Mustacchi                 pdev->kq_info.kwqe_left -= 1;
5461eef4f27bSRobert Mustacchi                 kwqe_free_rxq = (l2_kwqe_vm_free_rx_queue_t *) prod_qe;
5462eef4f27bSRobert Mustacchi             }
5463eef4f27bSRobert Mustacchi             pdev->kq_info.kwq_prod_qe = prod_qe;
5464eef4f27bSRobert Mustacchi             pdev->kq_info.kwq_prod_idx = prod_idx;
5465eef4f27bSRobert Mustacchi 
5466eef4f27bSRobert Mustacchi             MBQ_WR16(
5467eef4f27bSRobert Mustacchi                 pdev,
5468eef4f27bSRobert Mustacchi                 GET_CID(pdev->kq_info.kwq_cid_addr),
5469eef4f27bSRobert Mustacchi                 OFFSETOF(krnlq_context_t, krnlq_host_qidx),
5470eef4f27bSRobert Mustacchi                 prod_idx);
5471eef4f27bSRobert Mustacchi 
5472eef4f27bSRobert Mustacchi             return LM_STATUS_SUCCESS;
5473eef4f27bSRobert Mustacchi         }
5474eef4f27bSRobert Mustacchi         else
5475eef4f27bSRobert Mustacchi         {
5476eef4f27bSRobert Mustacchi             kwqe_free_rxq->queue_type = L2_NORMAL_QUEUE;
5477eef4f27bSRobert Mustacchi             kwqe_free_rxq->qid = (u8_t)q_group_id;
5478eef4f27bSRobert Mustacchi             pdev->kq_info.kwqe_left -= 1;
5479*55fea89dSDan Cross #if INCLUDE_OFLD_SUPPORT
5480eef4f27bSRobert Mustacchi             if(q_group_id == RX_CHAIN_IDX2 &&
5481eef4f27bSRobert Mustacchi                !s_list_is_empty(&pdev->rx_info.chain[RX_CHAIN_IDX1].active_descq))
5482eef4f27bSRobert Mustacchi             {
5483eef4f27bSRobert Mustacchi                 kwqe_free_rxq->flags = L2_KWQE_FLAGS_LAYER_MASK_L2;
5484*55fea89dSDan Cross                 kwqe_free_rxq->opcode = L2_KWQE_OPCODE_VALUE_VM_FREE_RX_QUEUE;
5485*55fea89dSDan Cross 
5486eef4f27bSRobert Mustacchi                 /* Advance to the next KWQE. */
5487eef4f27bSRobert Mustacchi                 if(prod_qe == pdev->kq_info.kwq_last_qe)
5488eef4f27bSRobert Mustacchi                 {
5489eef4f27bSRobert Mustacchi                     prod_qe = pdev->kq_info.kwq_virt;
5490eef4f27bSRobert Mustacchi                 }
5491eef4f27bSRobert Mustacchi                 else
5492eef4f27bSRobert Mustacchi                 {
5493eef4f27bSRobert Mustacchi                     prod_qe++;
5494eef4f27bSRobert Mustacchi                 }
5495eef4f27bSRobert Mustacchi                 prod_idx++;
5496*55fea89dSDan Cross 
5497eef4f27bSRobert Mustacchi                 /* flush the catchup RX queue too */
5498eef4f27bSRobert Mustacchi                 kwqe_free_rxq = (l2_kwqe_vm_free_rx_queue_t *) prod_qe;
5499eef4f27bSRobert Mustacchi                 kwqe_free_rxq->queue_type = L2_NORMAL_QUEUE;
5500eef4f27bSRobert Mustacchi                 kwqe_free_rxq->qid = (u8_t)RX_CHAIN_IDX1;
5501eef4f27bSRobert Mustacchi                 pdev->kq_info.kwqe_left -= 1;
5502eef4f27bSRobert Mustacchi             }
5503*55fea89dSDan Cross #endif
5504eef4f27bSRobert Mustacchi         }
5505eef4f27bSRobert Mustacchi     }
5506eef4f27bSRobert Mustacchi     else
5507eef4f27bSRobert Mustacchi     {
5508eef4f27bSRobert Mustacchi         kwqe_free_rxq->queue_type = L2_VM_QUEUE;
5509eef4f27bSRobert Mustacchi         kwqe_free_rxq->qid = (u8_t)q_group_id;
5510eef4f27bSRobert Mustacchi         pdev->kq_info.kwqe_left -= 1;
5511eef4f27bSRobert Mustacchi     }
5512eef4f27bSRobert Mustacchi     kwqe_free_rxq->flags = L2_KWQE_FLAGS_LAYER_MASK_L2;
5513*55fea89dSDan Cross     kwqe_free_rxq->opcode = L2_KWQE_OPCODE_VALUE_VM_FREE_RX_QUEUE;
5514eef4f27bSRobert Mustacchi 
5515eef4f27bSRobert Mustacchi     /* Advance to the next KWQE. */
5516eef4f27bSRobert Mustacchi     if(prod_qe == pdev->kq_info.kwq_last_qe)
5517eef4f27bSRobert Mustacchi     {
5518eef4f27bSRobert Mustacchi         prod_qe = pdev->kq_info.kwq_virt;
5519eef4f27bSRobert Mustacchi     }
5520eef4f27bSRobert Mustacchi     else
5521eef4f27bSRobert Mustacchi     {
5522eef4f27bSRobert Mustacchi         prod_qe++;
5523eef4f27bSRobert Mustacchi     }
5524eef4f27bSRobert Mustacchi     prod_idx++;
5525eef4f27bSRobert Mustacchi 
5526eef4f27bSRobert Mustacchi     pdev->kq_info.kwq_prod_qe = prod_qe;
5527eef4f27bSRobert Mustacchi     pdev->kq_info.kwq_prod_idx = prod_idx;
5528*55fea89dSDan Cross 
5529eef4f27bSRobert Mustacchi     MBQ_WR16(
5530eef4f27bSRobert Mustacchi         pdev,
5531eef4f27bSRobert Mustacchi         GET_CID(pdev->kq_info.kwq_cid_addr),
5532eef4f27bSRobert Mustacchi         OFFSETOF(krnlq_context_t, krnlq_host_qidx),
5533eef4f27bSRobert Mustacchi         prod_idx);
5534*55fea89dSDan Cross 
5535*55fea89dSDan Cross     return LM_STATUS_SUCCESS;
5536eef4f27bSRobert Mustacchi }
5537eef4f27bSRobert Mustacchi 
5538eef4f27bSRobert Mustacchi /*******************************************************************************
5539eef4f27bSRobert Mustacchi  * Description:
5540eef4f27bSRobert Mustacchi  *
5541eef4f27bSRobert Mustacchi  * Return:
5542eef4f27bSRobert Mustacchi  ******************************************************************************/
5543*55fea89dSDan Cross VOID
lm_update_defq_filter_ctx(lm_device_t * pdev,u8_t valid)5544eef4f27bSRobert Mustacchi lm_update_defq_filter_ctx(
5545eef4f27bSRobert Mustacchi     lm_device_t *pdev,
5546eef4f27bSRobert Mustacchi     u8_t valid
5547eef4f27bSRobert Mustacchi     )
5548eef4f27bSRobert Mustacchi {
5549eef4f27bSRobert Mustacchi     u32_t ctx_offset = pdev->vars.hw_filter_ctx_offset;
5550eef4f27bSRobert Mustacchi     u32_t val = 0;
5551eef4f27bSRobert Mustacchi 
5552eef4f27bSRobert Mustacchi     if(valid)
5553eef4f27bSRobert Mustacchi         val |= L2_VM_FILTER_MAC << 16;
5554*55fea89dSDan Cross 
5555eef4f27bSRobert Mustacchi     REG_WR_IND(
5556eef4f27bSRobert Mustacchi         pdev,
5557eef4f27bSRobert Mustacchi         OFFSETOF(reg_space_t, rxp.rxp_scratch[0])+ctx_offset,
5558eef4f27bSRobert Mustacchi         val);
5559eef4f27bSRobert Mustacchi }
5560eef4f27bSRobert Mustacchi 
5561eef4f27bSRobert Mustacchi /*******************************************************************************
5562eef4f27bSRobert Mustacchi  * Description:
5563eef4f27bSRobert Mustacchi  *
5564eef4f27bSRobert Mustacchi  * Return:
5565eef4f27bSRobert Mustacchi  ******************************************************************************/
5566eef4f27bSRobert Mustacchi lm_status_t
lm_chng_q_group_filter(lm_device_t * pdev,u32_t q_group_id,u8_t * dest_mac,u16_t * vlan_ptr,u32_t filter_id)5567eef4f27bSRobert Mustacchi lm_chng_q_group_filter(
5568eef4f27bSRobert Mustacchi     lm_device_t *pdev,
5569eef4f27bSRobert Mustacchi     u32_t q_group_id,
5570eef4f27bSRobert Mustacchi     u8_t  *dest_mac,
5571eef4f27bSRobert Mustacchi     u16_t *vlan_ptr,
5572eef4f27bSRobert Mustacchi     u32_t filter_id
5573eef4f27bSRobert Mustacchi     )
5574eef4f27bSRobert Mustacchi {
5575eef4f27bSRobert Mustacchi     kwqe_t *prod_qe;
5576eef4f27bSRobert Mustacchi     u16_t prod_idx;
5577*55fea89dSDan Cross 
5578eef4f27bSRobert Mustacchi     if(pdev->kq_info.kwqe_left < 1)
5579eef4f27bSRobert Mustacchi     {
5580eef4f27bSRobert Mustacchi         DbgMessage(pdev, WARN, "No more KWQE left.\n");
5581eef4f27bSRobert Mustacchi 
5582eef4f27bSRobert Mustacchi         pdev->kq_info.no_kwq_bd_left++;
5583eef4f27bSRobert Mustacchi 
5584eef4f27bSRobert Mustacchi         return LM_STATUS_RESOURCE;
5585eef4f27bSRobert Mustacchi     }
5586eef4f27bSRobert Mustacchi 
5587eef4f27bSRobert Mustacchi     prod_qe = pdev->kq_info.kwq_prod_qe;
5588eef4f27bSRobert Mustacchi     prod_idx = pdev->kq_info.kwq_prod_idx;
5589eef4f27bSRobert Mustacchi 
5590eef4f27bSRobert Mustacchi     pdev->kq_info.kwqe_left -= 1;
5591eef4f27bSRobert Mustacchi     if(dest_mac == NULL && vlan_ptr == NULL)
5592eef4f27bSRobert Mustacchi     {
5593eef4f27bSRobert Mustacchi         /* clear filter operation */
5594*55fea89dSDan Cross         l2_kwqe_vm_remove_rx_filter_t * kwqe_remove_rx_filter =
5595eef4f27bSRobert Mustacchi             (l2_kwqe_vm_remove_rx_filter_t *) prod_qe;
5596eef4f27bSRobert Mustacchi         kwqe_remove_rx_filter->flags = L2_KWQE_FLAGS_LAYER_MASK_L2;
5597eef4f27bSRobert Mustacchi         kwqe_remove_rx_filter->qid = (u8_t)q_group_id;
5598eef4f27bSRobert Mustacchi         kwqe_remove_rx_filter->filter_id = (u8_t)filter_id;
5599*55fea89dSDan Cross         kwqe_remove_rx_filter->opcode = L2_KWQE_OPCODE_VALUE_VM_REMOVE_RX_FILTER;
5600eef4f27bSRobert Mustacchi     }
5601eef4f27bSRobert Mustacchi     else
5602eef4f27bSRobert Mustacchi     {
5603eef4f27bSRobert Mustacchi         /* set filter operation */
5604*55fea89dSDan Cross         l2_kwqe_vm_set_rx_filter_t * kwqe_set_rx_filter =
5605eef4f27bSRobert Mustacchi             (l2_kwqe_vm_set_rx_filter_t *) prod_qe;
5606eef4f27bSRobert Mustacchi 
5607eef4f27bSRobert Mustacchi         kwqe_set_rx_filter->flags = L2_KWQE_FLAGS_LAYER_MASK_L2;
5608eef4f27bSRobert Mustacchi         kwqe_set_rx_filter->qid = (u8_t)q_group_id;
5609eef4f27bSRobert Mustacchi         kwqe_set_rx_filter->filter_id = (u8_t)filter_id;
5610eef4f27bSRobert Mustacchi         if(vlan_ptr)
5611eef4f27bSRobert Mustacchi         {
5612eef4f27bSRobert Mustacchi             kwqe_set_rx_filter->vlan = *vlan_ptr;
5613*55fea89dSDan Cross             kwqe_set_rx_filter->filter_type = L2_VM_FILTER_MAC_VLAN;
5614eef4f27bSRobert Mustacchi         }
5615eef4f27bSRobert Mustacchi         else
5616eef4f27bSRobert Mustacchi         {
5617*55fea89dSDan Cross             kwqe_set_rx_filter->filter_type = L2_VM_FILTER_MAC;
5618eef4f27bSRobert Mustacchi         }
5619*55fea89dSDan Cross         kwqe_set_rx_filter->opcode = L2_KWQE_OPCODE_VALUE_VM_SET_RX_FILTER;
5620eef4f27bSRobert Mustacchi     }
5621*55fea89dSDan Cross 
5622eef4f27bSRobert Mustacchi     /* Advance to the next KWQE. */
5623eef4f27bSRobert Mustacchi     if(prod_qe == pdev->kq_info.kwq_last_qe)
5624eef4f27bSRobert Mustacchi     {
5625eef4f27bSRobert Mustacchi         prod_qe = pdev->kq_info.kwq_virt;
5626eef4f27bSRobert Mustacchi     }
5627eef4f27bSRobert Mustacchi     else
5628eef4f27bSRobert Mustacchi     {
5629eef4f27bSRobert Mustacchi         prod_qe++;
5630eef4f27bSRobert Mustacchi     }
5631eef4f27bSRobert Mustacchi     prod_idx++;
5632eef4f27bSRobert Mustacchi 
5633eef4f27bSRobert Mustacchi     pdev->kq_info.kwq_prod_qe = prod_qe;
5634eef4f27bSRobert Mustacchi     pdev->kq_info.kwq_prod_idx = prod_idx;
5635*55fea89dSDan Cross 
5636eef4f27bSRobert Mustacchi     MBQ_WR16(
5637eef4f27bSRobert Mustacchi         pdev,
5638eef4f27bSRobert Mustacchi         GET_CID(pdev->kq_info.kwq_cid_addr),
5639eef4f27bSRobert Mustacchi         OFFSETOF(krnlq_context_t, krnlq_host_qidx),
5640eef4f27bSRobert Mustacchi         prod_idx);
5641*55fea89dSDan Cross     return LM_STATUS_PENDING;
5642eef4f27bSRobert Mustacchi }
5643eef4f27bSRobert Mustacchi 
5644eef4f27bSRobert Mustacchi /*******************************************************************************
5645eef4f27bSRobert Mustacchi  * Description:
5646eef4f27bSRobert Mustacchi  *
5647eef4f27bSRobert Mustacchi  * Return:
5648eef4f27bSRobert Mustacchi  ******************************************************************************/
5649eef4f27bSRobert Mustacchi u32_t
lm_service_l2_kcqes(struct _lm_device_t * pdev,kcqe_t * cqe_ptr[],u32_t num_cqes)5650eef4f27bSRobert Mustacchi lm_service_l2_kcqes(
5651eef4f27bSRobert Mustacchi     struct _lm_device_t *pdev,
5652eef4f27bSRobert Mustacchi     kcqe_t *cqe_ptr[],
5653eef4f27bSRobert Mustacchi     u32_t num_cqes)
5654eef4f27bSRobert Mustacchi {
5655eef4f27bSRobert Mustacchi     u32_t cqe_serviced_cnt;
5656eef4f27bSRobert Mustacchi     u32_t cqe_cnt;
5657eef4f27bSRobert Mustacchi     u8_t success;
5658eef4f27bSRobert Mustacchi     kcqe_t *kcqe;
5659eef4f27bSRobert Mustacchi     lm_status_t lm_status;
5660*55fea89dSDan Cross 
5661eef4f27bSRobert Mustacchi     cqe_serviced_cnt = 0;
5662eef4f27bSRobert Mustacchi     while(num_cqes)
5663eef4f27bSRobert Mustacchi     {
5664eef4f27bSRobert Mustacchi         /* Determine the number of cqes for a completion.  Some
5665eef4f27bSRobert Mustacchi          * completions span several cqes. */
5666eef4f27bSRobert Mustacchi         cqe_cnt = 0;
5667eef4f27bSRobert Mustacchi         while(cqe_ptr[cqe_cnt]->kcqe_flags & KCQE_FLAGS_NEXT)
5668eef4f27bSRobert Mustacchi         {
5669eef4f27bSRobert Mustacchi             cqe_cnt++;
5670eef4f27bSRobert Mustacchi         }
5671eef4f27bSRobert Mustacchi         cqe_cnt++;
5672eef4f27bSRobert Mustacchi 
5673eef4f27bSRobert Mustacchi         DbgBreakIf(cqe_cnt > num_cqes);
5674eef4f27bSRobert Mustacchi 
5675eef4f27bSRobert Mustacchi         kcqe = *cqe_ptr;
5676eef4f27bSRobert Mustacchi 
5677*55fea89dSDan Cross         DbgBreakIf((kcqe->kcqe_flags & KCQE_FLAGS_LAYER_MASK) !=
5678eef4f27bSRobert Mustacchi                     KCQE_FLAGS_LAYER_MASK_L2);
5679eef4f27bSRobert Mustacchi 
5680eef4f27bSRobert Mustacchi         switch(kcqe->kcqe_opcode)
5681eef4f27bSRobert Mustacchi         {
5682eef4f27bSRobert Mustacchi             case L2_KCQE_OPCODE_VALUE_VM_FREE_RX_QUEUE:
5683eef4f27bSRobert Mustacchi                 /* initiate rx buffer abort */
5684eef4f27bSRobert Mustacchi                 {
5685eef4f27bSRobert Mustacchi                     l2_kcqe_vm_free_rx_queue_t *kcqe_free_rxq;
5686*55fea89dSDan Cross 
5687eef4f27bSRobert Mustacchi                     kcqe_free_rxq = (l2_kcqe_vm_free_rx_queue_t *)kcqe;
5688eef4f27bSRobert Mustacchi                     mm_q_grp_abort_rx_request(
5689*55fea89dSDan Cross                         pdev,
5690eef4f27bSRobert Mustacchi                         kcqe_free_rxq->qid);
5691eef4f27bSRobert Mustacchi                 }
5692eef4f27bSRobert Mustacchi                 break;
5693*55fea89dSDan Cross 
5694eef4f27bSRobert Mustacchi             case L2_KCQE_OPCODE_VALUE_VM_SET_RX_FILTER:
5695eef4f27bSRobert Mustacchi             case L2_KCQE_OPCODE_VALUE_VM_REMOVE_RX_FILTER:
5696eef4f27bSRobert Mustacchi                 {
5697eef4f27bSRobert Mustacchi                     l2_kcqe_vm_set_rx_filter_t *kcqe_filter;
5698eef4f27bSRobert Mustacchi 
5699eef4f27bSRobert Mustacchi                     kcqe_filter = (l2_kcqe_vm_set_rx_filter_t *)kcqe;
5700eef4f27bSRobert Mustacchi                     if(kcqe_filter->status == SC_SUCCESS)
5701eef4f27bSRobert Mustacchi                     {
5702eef4f27bSRobert Mustacchi                         lm_status = LM_STATUS_SUCCESS;
5703eef4f27bSRobert Mustacchi                     }
5704eef4f27bSRobert Mustacchi                     else
5705eef4f27bSRobert Mustacchi                     {
5706eef4f27bSRobert Mustacchi                         lm_status = LM_STATUS_FAILURE;
5707eef4f27bSRobert Mustacchi                     }
5708eef4f27bSRobert Mustacchi                     mm_comp_l2_filter_chng_req(
5709*55fea89dSDan Cross                         pdev,
5710*55fea89dSDan Cross                         lm_status,
5711eef4f27bSRobert Mustacchi                         kcqe_filter->qid);
5712eef4f27bSRobert Mustacchi                 }
5713eef4f27bSRobert Mustacchi                 break;
5714eef4f27bSRobert Mustacchi 
5715eef4f27bSRobert Mustacchi             case L2_KCQE_OPCODE_VALUE_VM_ALLOC_RX_QUEUE:
5716eef4f27bSRobert Mustacchi             case L2_KCQE_OPCODE_VALUE_RX_PACKET:
5717eef4f27bSRobert Mustacchi             case L2_KCQE_OPCODE_VALUE_ENABLE_RSS:
5718eef4f27bSRobert Mustacchi             case L2_KCQE_OPCODE_VALUE_DISABLE_RSS:
5719eef4f27bSRobert Mustacchi             case L2_KCQE_OPCODE_VALUE_UPDATE_RSS:
5720eef4f27bSRobert Mustacchi             case L2_KCQE_OPCODE_VALUE_FLUSH_BD_CHAIN:
5721eef4f27bSRobert Mustacchi                 /* no need to do anything in the driver */
5722eef4f27bSRobert Mustacchi                 break;
5723*55fea89dSDan Cross 
5724eef4f27bSRobert Mustacchi             default:
5725eef4f27bSRobert Mustacchi                 DbgBreakMsg("invalid l2 kcqe.\n");
5726eef4f27bSRobert Mustacchi                 break;
5727eef4f27bSRobert Mustacchi         }
5728*55fea89dSDan Cross 
5729eef4f27bSRobert Mustacchi         cqe_ptr += cqe_cnt;
5730eef4f27bSRobert Mustacchi         num_cqes -= cqe_cnt;
5731eef4f27bSRobert Mustacchi         cqe_serviced_cnt += cqe_cnt;
5732eef4f27bSRobert Mustacchi     }
5733*55fea89dSDan Cross 
5734eef4f27bSRobert Mustacchi     return cqe_serviced_cnt;
5735eef4f27bSRobert Mustacchi }
5736eef4f27bSRobert Mustacchi #endif /* LM_NON_LEGACY_MODE_SUPPORT */
5737