xref: /illumos-gate/usr/src/uts/common/io/bnxe/577xx/drivers/common/lm/device/lm_devinfo.c (revision 6680ee99638d23c9c2561c782eb1df2176e04698)
1 /*******************************************************************************
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  *
21  * Copyright 2014 QLogic Corporation
22  * The contents of this file are subject to the terms of the
23  * QLogic End User License (the "License").
24  * You may not use this file except in compliance with the License.
25  *
26  * You can obtain a copy of the License at
27  * http://www.qlogic.com/Resources/Documents/DriverDownloadHelp/
28  * QLogic_End_User_Software_License.txt
29  * See the License for the specific language governing permissions
30  * and limitations under the License.
31  *
32  *
33  * Module Description:
34  *      This file contains functions having to do with Device info, licensing
35  *      and Bandwidth Allocation
36  *
37  ******************************************************************************/
38 
39 #include "lm5710.h"
40 
41 unsigned long log2_align(unsigned long n);
42 
lm_get_timestamp_of_recent_cid_recycling(struct _lm_device_t * pdev)43 u64_t lm_get_timestamp_of_recent_cid_recycling(struct _lm_device_t *pdev)
44 {
45     return pdev->vars.last_recycling_timestamp;
46 }
47 
lm_get_max_supported_toe_cons(struct _lm_device_t * pdev)48 u32_t lm_get_max_supported_toe_cons(struct _lm_device_t *pdev)
49 {
50     if ( CHK_NULL(pdev) )
51     {
52         return 0;
53     }
54     return pdev->params.max_supported_toe_cons;
55 }
56 
lm_get_toe_rss_possibility(struct _lm_device_t * pdev)57 u8_t lm_get_toe_rss_possibility(struct _lm_device_t *pdev)
58 {
59     if ( CHK_NULL(pdev) )
60     {
61         return 0;
62     }
63     return (pdev->params.l4_rss_is_possible != L4_RSS_DISABLED);
64 }
65 
66 /*******************************************************************************
67  * Description:
68  *     reads iscsi_boot info block from shmem
69  * Return:
70  *     lm_status
71  ******************************************************************************/
lm_get_iscsi_boot_info_block(struct _lm_device_t * pdev,struct _iscsi_info_block_hdr_t * iscsi_info_block_hdr_ptr)72 lm_status_t lm_get_iscsi_boot_info_block( struct _lm_device_t *pdev, struct _iscsi_info_block_hdr_t* iscsi_info_block_hdr_ptr )
73 {
74     u32_t           val                = 0;
75     u32_t           offset             = 0;
76     const u8_t      func_mb_id         = FUNC_MAILBOX_ID(pdev);
77 
78     // dummy variables so we have convenience way to know the shmem offsets
79                                                // This is a pointer so it doesn't load the stack.
80     // If we delete these lines we won't have shmem_region_t symbols
81     shmem_region_t*    shmem_region_dummy    = NULL;
82     shmem2_region_t*   shmem2_region_dummy   = NULL;
83     shared_hw_cfg_t*   shared_hw_cfg_dummy   = NULL;
84     port_hw_cfg_t*     port_hw_cfg_dummy     = NULL;
85     shared_feat_cfg_t* shared_feat_cfg_dummy = NULL;
86     port_feat_cfg_t*   port_feat_cfg_dummy   = NULL;
87     mf_cfg_t*          mf_cfg_dummy          = NULL;
88 
89     UNREFERENCED_PARAMETER_(shmem_region_dummy);
90     UNREFERENCED_PARAMETER_(shmem2_region_dummy);
91     UNREFERENCED_PARAMETER_(shared_hw_cfg_dummy);
92     UNREFERENCED_PARAMETER_(port_hw_cfg_dummy);
93     UNREFERENCED_PARAMETER_(shared_feat_cfg_dummy);
94     UNREFERENCED_PARAMETER_(port_feat_cfg_dummy);
95     UNREFERENCED_PARAMETER_(mf_cfg_dummy);
96 
97     if ( CHK_NULL( iscsi_info_block_hdr_ptr ) )
98     {
99         return LM_STATUS_INVALID_PARAMETER ;
100     }
101 
102     if (pdev->hw_info.mcp_detected == 1)
103     {
104         offset = OFFSETOF(shmem_region_t,func_mb[func_mb_id].iscsi_boot_signature);
105         LM_SHMEM_READ(pdev, offset, &val );
106         iscsi_info_block_hdr_ptr->signature = val ;
107         // only for debugging
108         offset = OFFSETOF(shmem_region_t,func_mb[func_mb_id].iscsi_boot_block_offset);
109         LM_SHMEM_READ(pdev, offset, &val );
110         if (val == UEFI_BOOT_SIGNATURE)
111         {
112             SET_FLAGS(iscsi_info_block_hdr_ptr->boot_flags, BOOT_INFO_FLAGS_UEFI_BOOT );
113         }
114         else
115         {
116             RESET_FLAGS(iscsi_info_block_hdr_ptr->boot_flags, BOOT_INFO_FLAGS_UEFI_BOOT );
117         }
118     }
119     else
120     {
121         // If mcp is detected the shmenm is not initialized and
122         iscsi_info_block_hdr_ptr->signature = 0;
123     }
124     return LM_STATUS_SUCCESS ;
125 }
126 
127 lm_status_t
lm_get_ibft_physical_addr_for_efi(struct _lm_device_t * pdev,u32_t * phy_hi,u32_t * phy_lo)128 lm_get_ibft_physical_addr_for_efi(
129     struct _lm_device_t *pdev, u32_t *phy_hi, u32_t *phy_lo
130     )
131 {
132     u32_t           offset             = 0;
133     u32_t           val                = 0;
134     const u8_t      func_mb_id         = FUNC_MAILBOX_ID(pdev);
135 
136     if (pdev->hw_info.mcp_detected == 1)
137     {
138         offset = OFFSETOF(shmem_region_t,func_mb[func_mb_id].iscsi_boot_signature);
139         LM_SHMEM_READ(pdev, offset, &val );
140         //iscsi_info_block_hdr_ptr->signature = val ;
141         // only for debugging
142         offset = OFFSETOF(shmem_region_t,func_mb[func_mb_id].iscsi_boot_block_offset);
143         LM_SHMEM_READ(pdev, offset, &val );
144         if (val == UEFI_BOOT_SIGNATURE)
145         {
146             offset = OFFSETOF(shmem2_region_t,ibft_host_addr);
147             LM_SHMEM2_READ(pdev, offset , &val);
148             *phy_lo = val;
149             *phy_hi = 0;
150 
151             return LM_STATUS_SUCCESS;
152         }
153     }
154     return LM_STATUS_FAILURE;
155 }
156 lm_status_t
lm_get_sriov_info(lm_device_t * pdev)157 lm_get_sriov_info(lm_device_t *pdev)
158 {
159     lm_status_t rc = LM_STATUS_SUCCESS;
160     u32_t val;
161     if (!CHIP_IS_E1x(pdev)) {
162         /* get bars... */
163 #ifdef VF_INVOLVED
164         rc = mm_get_sriov_info(pdev, &pdev->hw_info.sriov_info);
165         if (rc != LM_STATUS_SUCCESS) {
166             return rc;
167         }
168 #endif
169 
170 #ifdef __LINUX
171         lm_set_virt_mode(pdev, DEVICE_TYPE_PF, (pdev->hw_info.sriov_info.total_vfs? VT_BASIC_VF : VT_NONE));
172 #elif defined(_VBD_CMD_)
173         lm_set_virt_mode(pdev, DEVICE_TYPE_PF, (pdev->hw_info.sriov_info.total_vfs? VT_CHANNEL_VF : VT_NONE));
174 #endif
175         /* Since registers from 0x000-0x7ff are spilt across functions, each PF will have  the same location for the same 4 bits*/
176         val = REG_RD(pdev, PCICFG_OFFSET + GRC_CONFIG_REG_PF_INIT_VF);
177         pdev->hw_info.sriov_info.first_vf_in_pf = ((val & GRC_CR_PF_INIT_VF_PF_FIRST_VF_NUM_MASK) * 8) - E2_MAX_NUM_OF_VFS*PATH_ID(pdev);
178         DbgMessage(pdev, WARN, "First VF in PF = %d\n", pdev->hw_info.sriov_info.first_vf_in_pf);
179     }
180     return rc;
181 }
182 
183 
lm_print_func_info(lm_device_t * pdev)184 static void lm_print_func_info(lm_device_t *pdev)
185 {
186     DbgMessage(pdev, WARN, "lm_get_shmem_info: FUNC_ID: %d\n", FUNC_ID(pdev));
187     DbgMessage(pdev, WARN, "lm_get_shmem_info: PCI_FUNC_ID: %d\n", ABS_FUNC_ID(pdev));
188     DbgMessage(pdev, WARN, "lm_get_shmem_info: PORT_ID: %d\n", PORT_ID(pdev));
189 
190     if (CHIP_PORT_MODE(pdev) == LM_CHIP_PORT_MODE_4)
191     {
192         DbgMessage(pdev, WARN, "lm_get_shmem_info: ETH_PORT_ID: %d\n", PATH_ID(pdev) + 2*PORT_ID(pdev));
193     }
194     else
195     {
196         DbgMessage(pdev, WARN, "lm_get_shmem_info: ETH_PORT_ID: %d\n", PATH_ID(pdev) + PORT_ID(pdev));
197     }
198 
199     DbgMessage(pdev, WARN, "lm_get_shmem_info: PATH_ID: %d\n", PATH_ID(pdev));
200     DbgMessage(pdev, WARN, "lm_get_shmem_info: VNIC_ID: %d\n", VNIC_ID(pdev));
201     DbgMessage(pdev, WARN, "lm_get_shmem_info: FUNC_MAILBOX_ID: %d\n", FUNC_MAILBOX_ID(pdev));
202 
203 }
204 
205 
206 /*******************************************************************************
207  * Description:
208  *
209  * Return:
210  ******************************************************************************/
211 lm_status_t
lm_get_function_num(lm_device_t * pdev)212 lm_get_function_num(lm_device_t *pdev)
213 {
214     u32_t val = 0;
215     /* read the me register to get function number. */
216     /* Me register: holds the relative-function num + absolute-function num,
217      * absolute-function-num appears only from E2 and above. Before that these bits
218      * always contained zero, therefore we can't take as is. */
219     val = REG_RD(pdev, BAR_ME_REGISTER);
220     pdev->params.pfunc_rel = (u8_t)((val & ME_REG_PF_NUM) >> ME_REG_PF_NUM_SHIFT);
221     pdev->params.path_id = (u8_t)((val & ME_REG_ABS_PF_NUM) >> ME_REG_ABS_PF_NUM_SHIFT) & 1;
222 
223     if (CHIP_PORT_MODE(pdev) == LM_CHIP_PORT_MODE_4)
224     {
225         pdev->params.pfunc_abs = (pdev->params.pfunc_rel << 1) | pdev->params.path_id;
226     }
227     else
228     {
229         pdev->params.pfunc_abs = pdev->params.pfunc_rel | pdev->params.path_id;
230     }
231     pdev->params.pfunc_mb_id = FUNC_MAILBOX_ID(pdev);
232 
233     DbgMessage(pdev, INFORM , "relative function %d absolute function %d\n", pdev->params.pfunc_rel, pdev->params.pfunc_abs);
234 
235     lm_print_func_info(pdev);
236     return LM_STATUS_SUCCESS;
237 }
238 
239 
240 // reads max_payload_size & max_read_req_size from pci config space
lm_get_pcicfg_mps_mrrs(lm_device_t * pdev)241 lm_status_t lm_get_pcicfg_mps_mrrs(lm_device_t * pdev)
242 {
243     lm_status_t lm_status = LM_STATUS_SUCCESS;
244     u32_t       val       = 0;
245 
246     /* get max payload size and max read size we need it for pxp configuration
247     in the real chip it should be done by the MCP.*/
248     lm_status = mm_read_pci(pdev, PCICFG_DEVICE_CONTROL, &val);
249     if (lm_status != LM_STATUS_SUCCESS)
250     {
251         return lm_status;
252     }
253     // bit 5-7
254     pdev->hw_info.max_payload_size = (val & 0xe0)>>5;
255     // bit 12-14
256     pdev->hw_info.max_read_req_size = (val & 0x7000)>>12;
257     DbgMessage(pdev, INFORMi, "reg 0xd8 0x%x \n max_payload %d max_read_req %d \n",
258                 val,pdev->hw_info.max_payload_size,pdev->hw_info.max_read_req_size);
259 
260     return lm_status ;
261 }
262 
lm_get_pcicfg_info(lm_device_t * pdev)263 lm_status_t lm_get_pcicfg_info(lm_device_t *pdev)
264 {
265     lm_status_t lm_status;
266     u32_t val;
267     /* Get PCI device and vendor id. (need to be read from parent */
268     if (IS_PFDEV(pdev) || IS_CHANNEL_VFDEV(pdev))
269     {
270         lm_status = mm_read_pci(pdev, PCICFG_VENDOR_ID_OFFSET, &val);
271         if (lm_status != LM_STATUS_SUCCESS)
272         {
273             return lm_status;
274         }
275         if (val != 0xFFFFFFFF)
276         {
277             pdev->hw_info.vid = (u16_t) val;
278             pdev->hw_info.did = (u16_t) (val >> 16);
279         }
280         else if (IS_SW_CHANNEL_VIRT_MODE(pdev))
281         {
282             pdev->hw_info.vid = 0x14E4;
283             pdev->hw_info.did = 0x166F;
284         }
285         DbgMessage(pdev, INFORMi, "vid 0x%x\n", pdev->hw_info.vid);
286         DbgMessage(pdev, INFORMi, "did 0x%x\n", pdev->hw_info.did);
287     }
288     else
289     {
290         DbgMessage(pdev, WARN, "vid&did for VBD VF will be known later\n"); /*Must be known earlier*/
291     }
292     /* Get subsystem and subvendor id. */
293     lm_status = mm_read_pci(pdev, PCICFG_SUBSYSTEM_VENDOR_ID_OFFSET, &val);
294     if (lm_status != LM_STATUS_SUCCESS)
295     {
296         return lm_status;
297     }
298 
299     pdev->hw_info.svid = (u16_t) val;
300     DbgMessage(pdev, INFORMi, "svid 0x%x\n", pdev->hw_info.svid);
301     pdev->hw_info.ssid = (u16_t) (val >> 16);
302     DbgMessage(pdev, INFORMi, "ssid 0x%x\n", pdev->hw_info.ssid);
303 
304     /* Get IRQ, and interrupt pin. */
305     lm_status = mm_read_pci(pdev, PCICFG_INT_LINE, &val);
306     if (lm_status != LM_STATUS_SUCCESS)
307     {
308         return lm_status;
309     }
310     pdev->hw_info.irq = (u8_t) val;
311     DbgMessage(pdev, INFORMi, "IRQ 0x%x\n", pdev->hw_info.irq);
312     pdev->hw_info.int_pin = (u8_t) (val >> 8);
313     DbgMessage(pdev, INFORMi, "Int pin 0x%x\n", pdev->hw_info.int_pin);
314 
315     /* Get cache line size. */
316     lm_status = mm_read_pci(pdev, PCICFG_CACHE_LINE_SIZE, &val);
317     if (lm_status != LM_STATUS_SUCCESS)
318     {
319         return lm_status;
320     }
321 
322     pdev->hw_info.cache_line_size = (u8_t) val;
323     DbgMessage(pdev, INFORMi, "Cache line size 0x%x\n", (u8_t) val);
324     pdev->hw_info.latency_timer = (u8_t) (val >> 8);
325     DbgMessage(pdev, INFORMi, "Latency timer 0x%x\n", (u8_t) (val >> 8));
326 
327     /* Get PCI revision id. */
328     lm_status = mm_read_pci(pdev, PCICFG_REVISION_ID_OFFSET, &val);
329     if (lm_status != LM_STATUS_SUCCESS)
330     {
331         return lm_status;
332     }
333     pdev->hw_info.rev_id = (u8_t) val;
334     DbgMessage(pdev, INFORMi, "Revision id 0x%x\n", pdev->hw_info.rev_id);
335 
336     /* Get PCI-E speed*/
337     /* only for PF */
338     if (IS_PFDEV(pdev))
339     {
340         lm_status = mm_read_pci(pdev, PCICFG_LINK_CONTROL, &val);
341         if (lm_status != LM_STATUS_SUCCESS)
342         {
343             return lm_status;
344         }
345 
346         /* bit 20-25 */
347         pdev->hw_info.pcie_lane_width = (val & 0x3f00000) >> 20;
348         DbgMessage(pdev, INFORMi, "pcie_lane_width 0x%x\n", pdev->hw_info.pcie_lane_width);
349         /* bit 16 - 19 */
350         pdev->hw_info.pcie_lane_speed = (val & 0xf0000) >> 16;
351         DbgMessage(pdev, INFORMi, "pcie_lane_speed 0x%x\n", pdev->hw_info.pcie_lane_speed);
352 
353         lm_status = lm_get_pcicfg_mps_mrrs(pdev);
354     }
355 
356     // CQ61532 - Fan Failure test fails when stop the fan for more than 10 seconds and reboot.
357     // Actually most chances we won't get until here if the value is error = we might read other registers before that will hang the machine in Windows
358     // Hopefully this read will help with other LM drivers
359     // anyway, we'll fail the bind for that...
360     if (GET_FLAGS(pdev->hw_info.rev_id,PCICFG_REVESION_ID_MASK) == PCICFG_REVESION_ID_ERROR_VAL)
361     {
362         return LM_STATUS_FAILURE;
363     }
364 
365     return lm_status;
366 }
367 /**
368  * This function reads bar offset from PCI configuration
369  * header.
370  *
371  * @param _pdev
372  * @param bar_num Bar index: BAR_0 or BAR_1 or BAR_2
373  * @param bar_addr Output value (bar offset).
374  *
375  * @return LM_STATUS_SUCCESS if bar offset has been read
376  *         successfully.
377  */
lm_get_bar_offset_direct(IN struct _lm_device_t * pdev,IN u8_t bar_num,OUT lm_address_t * bar_addr)378 static __inline lm_status_t lm_get_bar_offset_direct(
379     IN   struct _lm_device_t * pdev,
380     IN   u8_t                  bar_num,   /* Bar index: BAR_0 or BAR_1 or BAR_2 */
381     OUT lm_address_t         * bar_addr )
382 {
383     u32_t pci_reg, val;
384     lm_status_t lm_status;
385     /* Get BARs addresses. */
386     switch (bar_num) {
387     case BAR_0:
388         pci_reg = PCICFG_BAR_1_LOW;
389         break;
390     case BAR_1:
391         pci_reg = PCICFG_BAR_1_LOW + 8;
392         break;
393     case BAR_2:
394         pci_reg = PCICFG_BAR_1_LOW + 16;
395         break;
396     default:
397         DbgMessage(pdev, FATAL, "Unsupported bar index: %d\n", bar_num);
398         DbgBreakIfAll(1);
399         return LM_STATUS_INVALID_PARAMETER;
400     }
401     lm_status = mm_read_pci(pdev, pci_reg, &val);
402     if(lm_status != LM_STATUS_SUCCESS) {
403         return lm_status;
404     }
405     bar_addr->as_u32.low = val & 0xfffffff0;;
406     DbgMessage(pdev, INFORMi, "BAR %d low 0x%x\n", bar_num,
407                 bar_addr->as_u32.low);
408     pci_reg += 4; /* sizeof configuration space bar address register */
409     lm_status = mm_read_pci(pdev, pci_reg, &val);
410     if(lm_status != LM_STATUS_SUCCESS) {
411         return lm_status;
412     }
413     bar_addr->as_u32.high = val;
414     DbgMessage(pdev, INFORMi, "BAR %d high 0x%x\n", bar_num,
415                 bar_addr->as_u32.high);
416     return LM_STATUS_SUCCESS;
417 }
418 
lm_get_bar_size_direct(IN lm_device_t * pdev,IN u8_t bar_num,OUT u32_t * val_p)419 static __inline lm_status_t lm_get_bar_size_direct (
420     IN  lm_device_t *pdev,
421     IN  u8_t bar_num,
422     OUT  u32_t * val_p)
423 {
424     u32_t bar_address = 0;
425     u32_t bar_size;
426     switch (bar_num) {
427     case BAR_0:
428         bar_address = GRC_CONFIG_2_SIZE_REG;
429         break;
430     case BAR_1:
431         bar_address = GRC_BAR2_CONFIG;
432         break;
433     case BAR_2:
434         bar_address = GRC_BAR3_CONFIG;
435         break;
436     default:
437         DbgMessage(pdev, FATAL, "Invalid Bar Num\n");
438         return LM_STATUS_INVALID_PARAMETER;
439     }
440     lm_reg_rd_ind(pdev,PCICFG_OFFSET + bar_address,&bar_size);
441     /*extract only bar size*/
442     ASSERT_STATIC(PCI_CONFIG_2_BAR1_SIZE == PCI_CONFIG_2_BAR2_SIZE);
443     ASSERT_STATIC(PCI_CONFIG_2_BAR2_SIZE == PCI_CONFIG_2_BAR3_SIZE);
444 
445     bar_size = (bar_size & PCI_CONFIG_2_BAR1_SIZE);
446     if (bar_size == 0)
447     {
448         /*bar size disabled*/
449         return LM_STATUS_FAILURE;
450     }
451     else
452     {
453         /*bit 1 stand for 64K each bit multiply it by two */
454         *val_p = (0x40 << ((bar_size - 1)))*0x400;
455     }
456 
457     return LM_STATUS_SUCCESS;
458 }
459 /* init pdev->hw_info with data from pcicfg */
lm_get_bars_info(lm_device_t * pdev)460 lm_status_t lm_get_bars_info(lm_device_t *pdev)
461 {
462     lm_status_t lm_status;
463     u32_t bar_map_size = 0;
464     u8_t i;
465 
466     /* Get BARs addresses. */
467     for (i = 0; i < ARRSIZE(pdev->hw_info.mem_base); i++)
468     {
469         lm_status = mm_get_bar_offset(pdev, i, &pdev->hw_info.mem_base[i]);
470         DbgMessage(pdev, INFORMi, "Bar_Offset=0x%x\n", pdev->hw_info.mem_base[i]);
471 
472         if(lm_status != LM_STATUS_SUCCESS)
473         {
474             return lm_status;
475         }
476         if(pdev->hw_info.mem_base[i].as_u64 == 0)
477         {
478             DbgMessage(pdev, WARNi, "BAR %d IS NOT PRESENT\n", i);
479             if(i==0)
480             {
481                 DbgBreakMsg("BAR 0 must be present\n");
482             }
483         }
484     }
485     /* TBA: review two intializations done in Teton here (are they needed? are they part of "get_bars_info"):
486     - Enable PCI bus master....
487     - Configure byte swap and enable write to the reg_window registers
488     */
489     for (i = 0; i < MAX_NUM_BAR; i++)
490     {
491         if(pdev->hw_info.mem_base[i].as_u64 == 0)
492         {
493             continue;
494         }
495 
496         /* get bar i size*/
497         lm_status = mm_get_bar_size(pdev, i, &(pdev->hw_info.bar_size[i]));
498 
499         if ( lm_status != LM_STATUS_SUCCESS )
500         {
501             return lm_status;
502         }
503         DbgMessage(pdev, INFORMi, "bar %d size 0x%x\n", i, pdev->hw_info.bar_size[i]);
504         /* Change in BAR1
505          * The function will map in case of BAR1 only the ETH cid doorbell space to a virtual address.
506          * (Map from BAR1 base address, to BAR1 base address plus MAX_ETH_CONS* LM_PAGE_SIZE).
507         */
508         if (BAR_1 == i )
509         {
510             if (IS_PFDEV(pdev))
511             { //TODO Revise it
512 #ifdef VF_INVOLVED
513                 bar_map_size = pdev->hw_info.bar_size[i];
514 #else
515                 bar_map_size = LM_DQ_CID_SIZE * MAX_ETH_CONS;
516 #endif
517             }
518             else
519             {
520                 bar_map_size = LM_DQ_CID_SIZE;
521             }
522 #ifndef VF_INVOLVED
523             DbgBreakIf(bar_map_size >= pdev->hw_info.bar_size[i]);
524 #endif
525         }
526         else
527         {
528             bar_map_size = pdev->hw_info.bar_size[i];
529         }
530         /* Map bar i to system address space. If not mapped already. */
531         if(lm_is_function_after_flr(pdev) ||
532 #ifdef VF_INVOLVED
533            lm_is_function_after_flr(PFDEV(pdev)) ||
534 #endif
535            (pdev->vars.mapped_bar_addr[i] == NULL))
536         {
537                 pdev->vars.mapped_bar_addr[i] = NULL;
538                 pdev->vars.mapped_bar_addr[i] = mm_map_io_base(
539                         pdev,
540                         pdev->hw_info.mem_base[i],
541                         bar_map_size,
542                         i);
543                 if(pdev->vars.mapped_bar_addr[i] == NULL)
544                 {
545                     DbgMessage(pdev, FATAL, "bar %d map io failed\n", i);
546                     return LM_STATUS_FAILURE;
547                 }
548                 else
549                 {
550                     DbgMessage(pdev, INFORMi, "mem_base[%d]=%p size=0x%x\n", i, pdev->vars.mapped_bar_addr[i], pdev->hw_info.bar_size[i]);
551                 }
552         }
553     }
554     /* Now that the bars are mapped, we need to enable target read + write and master-enable,
555      * we can't do this before bars are mapped, but we need to do this before we start any chip
556      * initializations... */
557 #if defined(__LINUX) || defined(_VBD_)
558     if (IS_PFDEV(pdev))
559     {
560         pdev->hw_info.pcie_caps_offset = mm_get_cap_offset(pdev, PCI_CAP_PCIE);
561         if (pdev->hw_info.pcie_caps_offset != 0 && pdev->hw_info.pcie_caps_offset != 0xFFFFFFFF)
562         {
563             mm_read_pci(pdev, pdev->hw_info.pcie_caps_offset + PCIE_DEV_CAPS, &pdev->hw_info.pcie_dev_capabilities);
564 
565             DbgMessage(pdev, WARN,"Device Capability of PCIe caps is %x\n",pdev->hw_info.pcie_dev_capabilities);
566 
567             if (pdev->hw_info.pcie_dev_capabilities)
568             {
569                 if (pdev->hw_info.pcie_dev_capabilities & PCIE_DEV_CAPS_FLR_CAPABILITY)
570                 {
571                     pdev->hw_info.flr_capable = TRUE;
572                 }
573                 else
574                 {
575                     pdev->hw_info.flr_capable = FALSE; /*Not trusted for PCI_CFG accesible via hypervisor*/
576                 }
577             }
578             else
579             {
580                 pdev->hw_info.pci_cfg_trust = PCI_CFG_NOT_TRUSTED;
581             }
582         }
583         else
584         {
585             pdev->hw_info.pci_cfg_trust = PCI_CFG_NOT_TRUSTED;
586         }
587 
588         if (!lm_is_function_after_flr(pdev))
589         {
590             pdev->hw_info.grc_didvid = REG_RD(pdev, (PCICFG_OFFSET + PCICFG_VENDOR_ID_OFFSET));
591             lm_status = mm_read_pci(pdev, PCICFG_VENDOR_ID_OFFSET, &pdev->hw_info.pci_cfg_didvid);
592             if (lm_status == LM_STATUS_SUCCESS)
593             {
594                 if (pdev->hw_info.grc_didvid != pdev->hw_info.pci_cfg_didvid)
595                 {
596                     pdev->hw_info.flr_capable = TRUE;
597                     pdev->params.is_flr = TRUE;
598                 }
599             }
600         }
601     }
602 #endif
603     if (lm_is_function_after_flr(pdev))
604     {
605         u32_t m_e,tr_e,tw_e;
606         u32_t i_cycles;
607         REG_WR(pdev, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1);
608         for (i_cycles = 0; i_cycles < 1000; i_cycles++)
609         {
610             mm_wait(pdev,999);
611         }
612         tr_e = REG_RD(pdev, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ);
613         tw_e = REG_RD(pdev, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_WRITE);
614         m_e = REG_RD(pdev, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER);
615         DbgMessage(pdev, INFORM, "M:0x%x, TR:0x%x, TW:0x%x\n",m_e,tr_e,tw_e);
616         if (tw_e != 0x1)
617         {
618             DbgBreakMsg("BAR 0 must be present\n");
619             return LM_STATUS_FAILURE;
620         }
621     }
622     return LM_STATUS_SUCCESS;
623 }
624 
lm_get_chip_id_and_mode(lm_device_t * pdev)625 lm_status_t lm_get_chip_id_and_mode(lm_device_t *pdev)
626 {
627     u32_t val;
628     u32_t chip_rev;
629 
630     /* Get the chip revision id and number. */
631     /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
632     val=REG_RD(PFDEV(pdev),MISC_REG_CHIP_NUM);
633     CHIP_NUM_SET(pdev->hw_info.chip_id,val);
634 
635     /* If OTP process was done on the device, change chip number to 57811 */
636     val=REG_RD(PFDEV(pdev),MISC_REG_CHIP_TYPE);
637     if (val & CHIP_OPT_MISC_DO_BIT)
638     {
639          switch (pdev->hw_info.chip_id)
640          {
641             case CHIP_NUM_57810:
642                 pdev->hw_info.chip_id = CHIP_NUM_57811;
643                 break;
644             case CHIP_NUM_57810_MF:
645                pdev->hw_info.chip_id = CHIP_NUM_57811_MF;
646                 break;
647             default:
648                 DbgMessage(pdev, FATAL, "Un-supported chip id for OTP: %d\n", pdev->hw_info.chip_id);
649                 DbgBreakIfAll(1);
650                 return LM_STATUS_FAILURE;
651          }
652     }
653 
654     val=REG_RD(PFDEV(pdev),MISC_REG_CHIP_REV);
655     // the chip rev is realy ASIC when it < 5
656     // when it > 5 odd mean FPGA even EMUL.
657     chip_rev = (val & 0xF)<<CHIP_REV_SHIFT;
658     pdev->hw_info.chip_id |= chip_rev;
659 
660     if(chip_rev <= CHIP_REV_ASIC_MAX)
661     {
662         pdev->vars.clk_factor = 1;
663     }
664     else if(chip_rev & CHIP_REV_SIM_IS_FPGA)
665     {
666         pdev->vars.clk_factor = LM_FPGA_FACTOR;
667         DbgMessage(pdev, INFORMi, "FPGA: forcing MPS from %d to 0.\n", pdev->hw_info.max_payload_size);
668         pdev->hw_info.max_payload_size = 0;
669     }
670     else
671     {
672         pdev->vars.clk_factor = LM_EMUL_FACTOR;
673     }
674 
675     val=REG_RD(PFDEV(pdev),MISC_REG_CHIP_METAL);
676     pdev->hw_info.chip_id |= (val & 0xff) << 4;
677     val=REG_RD(PFDEV(pdev),MISC_REG_BOND_ID);
678     pdev->hw_info.chip_id |= (val & 0xf);
679     DbgMessage(pdev, INFORMi , "chip id 0x%x\n", pdev->hw_info.chip_id);
680     /* Read silent revision */
681     val=REG_RD(PFDEV(pdev),MISC_REG_CHIP_TEST_REG);
682     pdev->hw_info.silent_chip_rev = (val & 0xff);
683     DbgMessage(pdev, INFORMi , "silent chip rev 0x%x\n", pdev->hw_info.silent_chip_rev);
684     if (!CHIP_IS_E1x(pdev))
685     {
686         /* Determine whether we are 2 port or 4 port mode */
687         /* read port4mode_en_ovwr[0];
688          * b)     if 0  read port4mode_en (0  2-port; 1  4-port);
689          * c)     if 1  read port4mode_en_ovwr[1] (0  2-port; 1  4-port);
690          */
691         val = REG_RD(PFDEV(pdev), MISC_REG_PORT4MODE_EN_OVWR);
692         DbgMessage(pdev, WARN, "MISC_REG_PORT4MODE_EN_OVWR = %d\n", val);
693         if ((val & 1) == 0)
694         {
695             val = REG_RD(PFDEV(pdev), MISC_REG_PORT4MODE_EN);
696         }
697         else
698         {
699             val = (val >> 1) & 1;
700         }
701         pdev->hw_info.chip_port_mode = val? LM_CHIP_PORT_MODE_4 : LM_CHIP_PORT_MODE_2;
702         DbgMessage(pdev, WARN, "chip_port_mode %s\n", (pdev->hw_info.chip_port_mode == LM_CHIP_PORT_MODE_4 )? "4_PORT" : "2_PORT");
703     }
704     else
705     {
706         pdev->hw_info.chip_port_mode = LM_CHIP_PORT_MODE_NONE; /* N/A */
707         DbgMessage(pdev, WARN, "chip_port_mode NONE\n");
708     }
709     return LM_STATUS_SUCCESS;
710 }
lm_get_igu_cam_info(lm_device_t * pdev)711 static void lm_get_igu_cam_info(lm_device_t *pdev)
712 {
713     lm_intr_blk_info_t *blk_info = &pdev->hw_info.intr_blk_info;
714     u8_t igu_test_vectors = FALSE;
715     #define IGU_CAM_VFID_MATCH(pdev, igu_fid) (!(igu_fid & IGU_FID_ENCODE_IS_PF) && ((igu_fid & IGU_FID_VF_NUM_MASK) == ABS_VFID(pdev)))
716     #define IGU_CAM_PFID_MATCH(pdev, igu_fid) ((igu_fid & IGU_FID_ENCODE_IS_PF) && ((igu_fid & IGU_FID_PF_NUM_MASK) == FUNC_ID(pdev)))
717     if (INTR_BLK_MODE(pdev) == INTR_BLK_MODE_BC)
718     {
719         blk_info->igu_info.igu_sb_cnt       = MAX_RSS_CHAINS;
720         blk_info->igu_info.igu_u_sb_offset  = 0;
721         if (CHIP_PORT_MODE(pdev) == LM_CHIP_PORT_MODE_2)
722         {
723             blk_info->igu_info.igu_base_sb      = VNIC_ID(pdev) * MAX_RSS_CHAINS;
724             blk_info->igu_info.igu_dsb_id       = MAX_VNIC_NUM * MAX_RSS_CHAINS + VNIC_ID(pdev);
725         }
726         else
727         {
728             blk_info->igu_info.igu_base_sb      = FUNC_ID(pdev) * MAX_RSS_CHAINS;
729             blk_info->igu_info.igu_dsb_id       = MAX_VNIC_NUM * MAX_RSS_CHAINS + FUNC_ID(pdev);
730         }
731     }
732     else
733     {
734         u8_t igu_sb_id;
735         u8_t fid;
736         u8_t vec;
737         u8_t vf_id;
738         u32_t val;
739         u8_t current_pf_id = 0;
740         u8_t recent_vf_id = 0xFF;
741         blk_info->igu_info.igu_sb_cnt = 0;
742         blk_info->igu_info.igu_test_sb_cnt = 0;
743         blk_info->igu_info.igu_base_sb = 0xff;
744         for (vf_id = 0; vf_id < E2_MAX_NUM_OF_VFS; vf_id++)
745         {
746             blk_info->igu_info.vf_igu_info[vf_id].igu_base_sb = 0xFF;
747             blk_info->igu_info.vf_igu_info[vf_id].igu_sb_cnt = 0;
748             blk_info->igu_info.vf_igu_info[vf_id].igu_test_sb_cnt = 0;
749             blk_info->igu_info.vf_igu_info[vf_id].igu_test_mode = FALSE;
750         }
751         for (igu_sb_id = 0; igu_sb_id < IGU_REG_MAPPING_MEMORY_SIZE; igu_sb_id++ )
752         {
753             // mapping CAM; relevant for E2 operating mode only.
754             // [0] - valid.
755             // [6:1] - vector number;
756             // [13:7] - FID (if VF - [13] = 0; [12:7] = VF number; if PF - [13] = 1; [12:9] = 0; [8:7] = PF number);
757             lm_igu_block_t * lm_igu_sb = &IGU_SB(pdev,igu_sb_id);
758             lm_igu_sb->block_dump = val = REG_RD(PFDEV(pdev), IGU_REG_MAPPING_MEMORY + 4*igu_sb_id);
759             DbgMessage(pdev, WARN, "addr:0x%x IGU_CAM[%d]=%x\n",IGU_REG_MAPPING_MEMORY + 4*igu_sb_id, igu_sb_id, val);
760             if (!(val & IGU_REG_MAPPING_MEMORY_VALID))
761             {
762                 if (!IS_MULTI_VNIC(pdev) && (CHIP_PORT_MODE(pdev) == LM_CHIP_PORT_MODE_2))
763                 {
764                     lm_igu_sb->status = LM_IGU_STATUS_AVAILABLE;
765                 }
766                 else if (current_pf_id == FUNC_ID(pdev))
767                 {
768                     lm_igu_sb->status = LM_IGU_STATUS_AVAILABLE;
769                 }
770                 else
771                 {
772                     lm_igu_sb->status = 0;
773                 }
774                 continue;
775             }
776             else
777             {
778                 lm_igu_sb->status = LM_IGU_STATUS_VALID;
779             }
780             fid = (val & IGU_REG_MAPPING_MEMORY_FID_MASK) >> IGU_REG_MAPPING_MEMORY_FID_SHIFT;
781             if (fid & IGU_FID_ENCODE_IS_PF)
782             {
783                 current_pf_id = lm_igu_sb->pf_number = fid & IGU_FID_PF_NUM_MASK;
784                 if (lm_igu_sb->pf_number == FUNC_ID(pdev))
785                 {
786                     lm_igu_sb->status |= (LM_IGU_STATUS_AVAILABLE | LM_IGU_STATUS_PF);
787                 }
788                 else
789                 {
790                     lm_igu_sb->status |= LM_IGU_STATUS_PF;
791                 }
792             }
793             else
794             {
795                 lm_igu_sb->vf_number = fid & IGU_FID_VF_NUM_MASK;
796                 if ((lm_igu_sb->vf_number >= pdev->hw_info.sriov_info.first_vf_in_pf)
797                     && (lm_igu_sb->vf_number < (pdev->hw_info.sriov_info.first_vf_in_pf + pdev->hw_info.sriov_info.total_vfs)))
798                 {
799                     lm_igu_sb->status |= LM_IGU_STATUS_AVAILABLE;
800                 }
801             }
802             lm_igu_sb->vector_number = (val & IGU_REG_MAPPING_MEMORY_VECTOR_MASK) >> IGU_REG_MAPPING_MEMORY_VECTOR_SHIFT;
803             DbgMessage(pdev, VERBOSEi, "FID[%d]=%d\n", igu_sb_id, fid);
804             if ((IS_PFDEV(pdev) && IGU_CAM_PFID_MATCH(pdev, fid)) ||
805                 (IS_VFDEV(pdev) && IGU_CAM_VFID_MATCH(pdev, fid)))
806             {
807                 vec = (val & IGU_REG_MAPPING_MEMORY_VECTOR_MASK) >> IGU_REG_MAPPING_MEMORY_VECTOR_SHIFT;
808                 DbgMessage(pdev, INFORMi, "VEC[%d]=%d\n", igu_sb_id, vec);
809                 if (igu_test_vectors)
810                 {
811                     blk_info->igu_info.igu_test_sb_cnt++;
812                 }
813                 else
814                 {
815                     if (vec == 0 && IS_PFDEV(pdev))
816                     {
817                         /* default status block for default segment + attn segment */
818                         blk_info->igu_info.igu_dsb_id = igu_sb_id;
819                     }
820                     else
821                     {
822                         if (blk_info->igu_info.igu_base_sb == 0xff)
823                         {
824                             blk_info->igu_info.igu_base_sb = igu_sb_id;
825                         }
826                         /* we don't count the default */
827                         blk_info->igu_info.igu_sb_cnt++;
828                     }
829                 }
830                 if (recent_vf_id != 0xFF)
831                 {
832                     if (!blk_info->igu_info.vf_igu_info[recent_vf_id].igu_test_mode)
833                     {
834                         DbgMessage(pdev, WARN, "Consecutiveness of IGU for VF%d is broken. My be it's IGU test mode\n",recent_vf_id);
835                     }
836                     blk_info->igu_info.vf_igu_info[recent_vf_id].igu_test_mode = TRUE;
837                 }
838             }
839             else if (IS_CHANNEL_VIRT_MODE_MASTER_PFDEV(pdev))
840             {
841                 if (!(fid & IGU_FID_ENCODE_IS_PF))
842                 {
843                      vf_id = fid & IGU_FID_VF_NUM_MASK;
844                      if (blk_info->igu_info.vf_igu_info[vf_id].igu_base_sb == 0xff)
845                      {
846                          blk_info->igu_info.vf_igu_info[vf_id].igu_base_sb = igu_sb_id;
847                      }
848                      /* we don't count the default */
849                      if (recent_vf_id != vf_id)
850                      {
851                          if (recent_vf_id != 0xFF)
852                          {
853                              if (!blk_info->igu_info.vf_igu_info[recent_vf_id].igu_test_mode)
854                              {
855                                  DbgMessage(pdev, WARN, "Consecutiveness of IGU for VF%d is broken. My be it's IGU test mode\n",recent_vf_id);
856                              }
857                              blk_info->igu_info.vf_igu_info[recent_vf_id].igu_test_mode = TRUE;
858                          }
859                      }
860                      recent_vf_id = vf_id;
861                      if (blk_info->igu_info.vf_igu_info[vf_id].igu_test_mode)
862                      {
863                          blk_info->igu_info.vf_igu_info[vf_id].igu_test_sb_cnt++;
864                      }
865                      else
866                      {
867                          blk_info->igu_info.vf_igu_info[vf_id].igu_sb_cnt++;
868                      }
869                 }
870                 else
871                 {
872                     if (recent_vf_id != 0xFF)
873                     {
874                         if (!blk_info->igu_info.vf_igu_info[recent_vf_id].igu_test_mode)
875                         {
876                                 DbgMessage(pdev, WARN, "Consecutiveness of IGU for VF%d is broken. My be it's IGU test mode\n",recent_vf_id);
877                         }
878                         blk_info->igu_info.vf_igu_info[recent_vf_id].igu_test_mode = TRUE;
879                     }
880                 }
881                 if (blk_info->igu_info.igu_base_sb != 0xff)
882                 {
883                     /* We've already found our base... but now we don't match... these are now igu-test-vectors */
884                     if (!igu_test_vectors)
885                     {
886                             DbgMessage(pdev, WARN, "Consecutiveness of IGU is broken. My be it's IGU test mode\n");
887                     }
888                     igu_test_vectors = TRUE; //TODO Michals: take care of this!!!e2 igu_test will fail.
889                 }
890             }
891             else
892             {
893                 /* No Match - belongs to someone else, check if breaks consecutiveness, if so, break at this point
894                  * driver doesn't support non-consecutive vectors (EXCEPT Def sb...) */
895                 if (blk_info->igu_info.igu_base_sb != 0xff)
896                 {
897                     /* We've already found our base... but now we don't match... these are now igu-test-vectors */
898                     if (!igu_test_vectors) {
899                         DbgMessage(pdev, WARN, "Consecutiveness of IGU is broken. My be it's IGU test mode\n");
900                     }
901                     igu_test_vectors = TRUE; //TODO Michals: take care of this!!!e2 igu_test will fail.
902                 }
903             }
904         }
905         // TODO check cam is valid...
906 #ifndef _VBD_
907         blk_info->igu_info.igu_sb_cnt = min(blk_info->igu_info.igu_sb_cnt, (u8_t)16);
908 #endif
909         /* E2 TODO: if we don't want to separate u/c/ producers in IGU, this line needs to
910          * be removed, and igu_u_offset needs to be set to 'zero'
911         blk_info->igu_info.igu_u_sb_offset = blk_info->igu_info.igu_sb_cnt / 2;*/
912         DbgMessage(pdev, WARN, "igu_sb_cnt=%d igu_dsb_id=%d igu_base_sb = %d igu_us_sb_offset = %d igu_test_cnt=%d\n",
913                     blk_info->igu_info.igu_sb_cnt, blk_info->igu_info.igu_dsb_id, blk_info->igu_info.igu_base_sb, blk_info->igu_info.igu_u_sb_offset,
914                     blk_info->igu_info.igu_test_sb_cnt);
915 
916         /* CQ61438 - do not show this error message in case of mf mode changed to SF and func >= 2*/
917         if ((FUNC_ID(pdev) < 2) && (pdev->hw_info.mf_info.mf_mode != SINGLE_FUNCTION))
918         {
919             if (blk_info->igu_info.igu_sb_cnt < 1)
920             {
921                 DbgMessage(pdev, FATAL, "Igu sb cnt is not valid value=%d\n", blk_info->igu_info.igu_sb_cnt);
922             }
923             if (blk_info->igu_info.igu_base_sb == 0xff)
924             {
925                 DbgMessage(pdev, FATAL, "Igu base sb is not valid value=%d\n", blk_info->igu_info.igu_base_sb);
926             }
927         }
928 
929 #define IGU_MAX_INTA_SB_CNT 31
930 
931         /* CQ72933/CQ72546
932            In case we are in INTA mode, we limit the igu count to 31 as we can't handle more than that */
933         if (pdev->params.b_inta_mode_prvided_by_os && (blk_info->igu_info.igu_sb_cnt > IGU_MAX_INTA_SB_CNT ))
934         {
935             blk_info->igu_info.igu_sb_cnt = IGU_MAX_INTA_SB_CNT ;
936         }
937     }
938 
939     DbgMessage(pdev, WARN, "IGU CAM INFO: BASE_SB: %d DSB: %d IGU_SB_CNT: %d\n", blk_info->igu_info.igu_base_sb, blk_info->igu_info.igu_dsb_id, blk_info->igu_info.igu_sb_cnt);
940 }
941 /*
942  * Assumptions:
943  *  - the following are initialized before call to this function:
944  *    chip-id, func-rel,
945  */
lm_get_intr_blk_info(lm_device_t * pdev)946 lm_status_t lm_get_intr_blk_info(lm_device_t *pdev)
947 {
948     lm_intr_blk_info_t *blk_info = &pdev->hw_info.intr_blk_info;
949     u32_t bar_base;
950     u8_t igu_func_id = 0;
951 
952     if (CHIP_IS_E1x(pdev))
953     {
954         blk_info->blk_type         = INTR_BLK_HC;
955         blk_info->access_type      = INTR_BLK_ACCESS_GRC;
956         blk_info->blk_mode         = INTR_BLK_MODE_NORM;
957         blk_info->simd_addr_womask = HC_REG_COMMAND_REG + PORT_ID(pdev)*32 + COMMAND_REG_SIMD_NOMASK;
958         /* The next part is tricky... and has to do with an emulation work-around for handling interrupts, in which
959          * we want to read without mask - always... so we take care of it here, instead of changing different ums to
960          * call approriate function */
961         if (CHIP_REV_IS_EMUL(pdev))
962         {
963             blk_info->simd_addr_wmask = HC_REG_COMMAND_REG + PORT_ID(pdev)*32 + COMMAND_REG_SIMD_NOMASK;
964         }
965         else
966         {
967             blk_info->simd_addr_wmask = HC_REG_COMMAND_REG + PORT_ID(pdev)*32 + COMMAND_REG_SIMD_MASK;
968         }
969     }
970     else
971     {
972         /* If we have more than 32 status blocks we'll need to read from IGU_REG_SISR_MDPC_WMASK_UPPER */
973         ASSERT_STATIC(MAX_RSS_CHAINS <= 32);
974         pdev->hw_info.intr_blk_info.blk_type = INTR_BLK_IGU;
975         if (REG_RD(PFDEV(pdev), IGU_REG_BLOCK_CONFIGURATION) & IGU_BLOCK_CONFIGURATION_REG_BACKWARD_COMP_EN)
976         {
977             DbgMessage(pdev, FATAL, "IGU Backward Compatible Mode\n");
978             blk_info->blk_mode = INTR_BLK_MODE_BC;
979         }
980         else
981         {
982             DbgMessage(pdev, WARN, "IGU Normal Mode\n");
983             blk_info->blk_mode = INTR_BLK_MODE_NORM;
984         }
985         /* read CAM to get igu info (must be called after we know if we're in backward compatible mode or not )*/
986         lm_get_igu_cam_info(pdev);
987 
988         igu_func_id = (1 << IGU_FID_ENCODE_IS_PF_SHIFT) | FUNC_ID(pdev);
989         blk_info->igu_info.igu_func_id = igu_func_id;
990         if (pdev->params.igu_access_mode == INTR_BLK_ACCESS_GRC)
991         {
992             DbgMessage(pdev, FATAL, "IGU -  GRC\n");
993             if (IS_VFDEV(pdev))
994             {
995                 DbgBreakMsg("VF Can't work in GRC Access mode!\n");
996                 return LM_STATUS_FAILURE;
997             }
998             blk_info->access_type = INTR_BLK_ACCESS_GRC;
999             /* [18:12] - FID (if VF - [18] = 0; [17:12] = VF number; if PF - [18] = 1; [17:14] = 0; [13:12] = PF number) */
1000             blk_info->cmd_ctrl_rd_womask =
1001             ((IGU_REG_SISR_MDPC_WOMASK_UPPER << IGU_CTRL_REG_ADDRESS_SHIFT) |
1002              (igu_func_id << IGU_CTRL_REG_FID_SHIFT) |
1003              (IGU_CTRL_CMD_TYPE_RD << IGU_CTRL_REG_TYPE_SHIFT));
1004             blk_info->simd_addr_womask = IGU_REG_COMMAND_REG_32LSB_DATA; /* this is where data will be after writing ctrol reg... */
1005             /* The next part is tricky... and has to do with an emulation work-around for handling interrupts, in which
1006              * we want to read without mask - always... so we take care of it here, instead of changing different ums to
1007              * call approriate function */
1008             if (CHIP_REV_IS_EMUL(pdev))
1009             {
1010                 blk_info->cmd_ctrl_rd_wmask =
1011                 ((IGU_REG_SISR_MDPC_WOMASK_UPPER << IGU_CTRL_REG_ADDRESS_SHIFT) |
1012                  (igu_func_id << IGU_CTRL_REG_FID_SHIFT) |
1013                  (IGU_CTRL_CMD_TYPE_RD << IGU_CTRL_REG_TYPE_SHIFT));
1014             }
1015             else
1016             {
1017                 blk_info->cmd_ctrl_rd_wmask =
1018                 ((IGU_REG_SISR_MDPC_WMASK_LSB_UPPER << IGU_CTRL_REG_ADDRESS_SHIFT) |
1019                  (igu_func_id << IGU_CTRL_REG_FID_SHIFT) |
1020                  (IGU_CTRL_CMD_TYPE_RD << IGU_CTRL_REG_TYPE_SHIFT));
1021             }
1022             blk_info->simd_addr_wmask = IGU_REG_COMMAND_REG_32LSB_DATA; /* this is where data will be after writing ctrol reg... */
1023         }
1024         else
1025         {
1026             DbgMessage(pdev, WARN, "IGU  - IGUMEM\n");
1027             blk_info->access_type = INTR_BLK_ACCESS_IGUMEM;
1028             bar_base = IS_PFDEV(pdev)? BAR_IGU_INTMEM : VF_BAR0_IGU_OFFSET;
1029             blk_info->simd_addr_womask = bar_base + IGU_REG_SISR_MDPC_WOMASK_UPPER*8;
1030             /* The next part is tricky... and has to do with an emulation work-around for handling interrupts, in which
1031              * we want to read without mask - always... so we take care of it here, instead of changing different ums to
1032              * call approriate function */
1033             if (CHIP_REV_IS_EMUL(pdev))
1034             {
1035                 blk_info->simd_addr_wmask = bar_base + IGU_REG_SISR_MDPC_WOMASK_UPPER*8;
1036             }
1037             else
1038             {
1039                 blk_info->simd_addr_wmask = bar_base + IGU_REG_SISR_MDPC_WMASK_LSB_UPPER*8;
1040             }
1041         }
1042     }
1043     return LM_STATUS_SUCCESS;
1044 }
1045 
lm_get_nvm_info(lm_device_t * pdev)1046 lm_status_t lm_get_nvm_info(lm_device_t *pdev)
1047 {
1048     u32_t val = REG_RD(pdev,MCP_REG_MCPR_NVM_CFG4);
1049 
1050     pdev->hw_info.flash_spec.total_size = NVRAM_1MB_SIZE << (val & MCPR_NVM_CFG4_FLASH_SIZE);
1051     pdev->hw_info.flash_spec.page_size  = NVRAM_PAGE_SIZE;
1052 
1053     return LM_STATUS_SUCCESS;
1054 }
1055 #if defined(DOS) || defined(__LINUX)
1056 /* for ediag + lediat we don't really care about licensing!... */
1057 #define DEFAULT_CONNECTIONS_TOE 1880
1058 #define MAX_CONNECTIONS         2048  /* Max 32K Connections per port / vnic-per-port (rounded  to power2)*/
1059 #define MAX_CONNECTIONS_ISCSI    128
1060 #define MAX_CONNECTIONS_RDMA      10
1061 #define MAX_CONNECTIONS_TOE     1880
1062 #define MAX_CONNECTIONS_FCOE       0
1063 #define MAX_CONNECTIONS_VF       128
1064 
1065 #else
1066 
1067 #define MAX_CONNECTIONS (min(16384,(32768 / (log2_align(pdev->hw_info.mf_info.vnics_per_port)))))  /* Max 32K Connections per port / vnic-per-port (rounded  to power2)
1068                                                                                                    but no more 16K to limit ilt client page size by 64KB*/
1069 
1070 #define DEFAULT_CONNECTIONS_TOE 1880
1071 #define MAX_CONNECTIONS_ISCSI    128
1072 #define MAX_CONNECTIONS_RDMA      10
1073 #define MAX_CONNECTIONS_FCOE    1024
1074 #define MAX_CONNECTIONS_VF      (1 << (LM_VF_MAX_RVFID_SIZE + LM_MAX_VF_CID_WND_SIZE + 1))
1075 #define MAX_CONNECTIONS_TOE     (min(8192,MAX_CONNECTIONS - MAX_CONNECTIONS_ISCSI - MAX_CONNECTIONS_RDMA - MAX_CONNECTIONS_FCOE - MAX_ETH_CONS - MAX_CONNECTIONS_VF))
1076 
1077 #endif
1078 
1079 
1080 #define MAX_CONNECTIONS_TOE_NO_LICENSE   0
1081 #define MAX_CONNECTIONS_ISCSI_NO_LICENSE 0
1082 #define MAX_CONNECTIONS_RDMA_NO_LICENSE  0
1083 #define MAX_CONNECTIONS_FCOE_NO_LICENSE  0
1084 
1085 #define MAX_CONNECTIONS_FCOE_NO_MCP      128
1086 
lm_parse_license_info(u32 val,u8_t is_high)1087 static u32_t lm_parse_license_info(u32 val, u8_t is_high)
1088 {
1089     if (is_high)
1090     {
1091         val &=0xFFFF0000;
1092         if(val)
1093         {
1094             val ^= FW_ENCODE_32BIT_PATTERN;
1095         }
1096         val >>= 16;
1097     }
1098     else
1099     {
1100         val &= 0xffff;
1101         if(val)
1102         {
1103             val ^= FW_ENCODE_16BIT_PATTERN;
1104         }
1105     }
1106     return val;
1107 }
1108 
lm_parse_license_info_bounded(u32 val,u32_t max_cons,u8_t is_high)1109 static u32_t lm_parse_license_info_bounded(u32 val, u32_t max_cons, u8_t is_high)
1110 {
1111     u32_t license_from_shmem =0;
1112     license_from_shmem = lm_parse_license_info(val, is_high);
1113 
1114     val = min(license_from_shmem, max_cons);
1115     return val;
1116 }
1117 /* No special MCP handling for a specific E1H configuration */
1118 /* WARNING: Do Not Change these defines!!! They are used in an external tcl script that assumes their values!!! */
1119 #define NO_MCP_WA_CFG_SET_ADDR            (0xA0000)
1120 #define NO_MCP_WA_CFG_SET_MAGIC           (0x88AA55FF)
1121 #define NO_MCP_WA_MULTI_VNIC_MODE         (0xA0004)
1122 #define NO_MCP_WA_VNICS_PER_PORT(port)    (0xA0008 + 4*(port))
1123 #define NO_MCP_WA_OVLAN(func)             (0xA0010 + 4*(func)) // --> 0xA0030
1124 #define NO_MCP_WA_FORCE_5710              (0xA0030)
1125 #define NO_MCP_WA_VALID_LIC_ADDR          (0xA0040)
1126 #define NO_MCP_WA_VALID_LIC_MAGIC         (0xCCAAFFEE)
1127 #define NO_MCP_WA_TOE_LIC                 (0xA0048)
1128 #define NO_MCP_WA_ISCSI_LIC               (0xA0050)
1129 #define NO_MCP_WA_RDMA_LIC                (0xA0058)
1130 #define NO_MCP_WA_CLC_SHMEM               (0xAF900)
1131 
lm_get_shmem_license_info(lm_device_t * pdev)1132 static lm_status_t lm_get_shmem_license_info(lm_device_t *pdev)
1133 {
1134     u32_t max_toe_cons[PORT_MAX]           = {0,0};
1135     u32_t max_rdma_cons[PORT_MAX]          = {0,0};
1136     u32_t max_iscsi_cons[PORT_MAX]         = {0,0};
1137     u32_t max_fcoe_cons[PORT_MAX]          = {0,0};
1138     u32_t max_eth_cons[PORT_MAX]           = {0,0}; /* Includes VF connections */
1139     u32_t max_bar_supported_cons[PORT_MAX] = {0};
1140     u32_t max_supported_cons[PORT_MAX]     = {0};
1141     u32_t val                              = 0;
1142     u8_t  port                             = 0;
1143     u32_t offset                           = 0;
1144 
1145     /* Even though only one port actually does the initialization, ALL functions need to know the maximum number of connections
1146      * because that's how they know what the page-size-is, and based on that do per-function initializations as well. */
1147     pdev->hw_info.max_common_conns = 0;
1148 
1149     /* get values for relevant ports. */
1150     for (port = 0; port < PORT_MAX; port++)
1151     {
1152         if (pdev->hw_info.mcp_detected == 1)
1153         {
1154             LM_SHMEM_READ(pdev, OFFSETOF(shmem_region_t, validity_map[port]),&val);
1155 
1156             // check that licensing is enabled
1157             if(GET_FLAGS(val, SHR_MEM_VALIDITY_LIC_MANUF_KEY_IN_EFFECT | SHR_MEM_VALIDITY_LIC_UPGRADE_KEY_IN_EFFECT))
1158             {
1159                 // align to 32 bit
1160                 offset = OFFSETOF(shmem_region_t, drv_lic_key[port].max_toe_conn) & 0xfffffffc;
1161                 LM_SHMEM_READ(pdev, offset, &val);
1162                 max_toe_cons[port] = lm_parse_license_info_bounded(val, MAX_CONNECTIONS_TOE,FALSE);
1163                 DbgMessage(pdev, INFORMi, "max_toe_conn from shmem %d for port %d\n",val, port);
1164                 /* RDMA */
1165                 offset = OFFSETOF(shmem_region_t, drv_lic_key[port].max_um_rdma_conn) & 0xfffffffc;
1166                 LM_SHMEM_READ(pdev, offset, &val);
1167                 max_rdma_cons[port] = lm_parse_license_info_bounded(val, MAX_CONNECTIONS_RDMA,FALSE);
1168                 DbgMessage(pdev, INFORMi, "max_rdma_conn from shmem %d for port %d\n",val, port);
1169                 /* ISCSI */
1170                 offset = OFFSETOF(shmem_region_t, drv_lic_key[port].max_iscsi_trgt_conn) & 0xfffffffc;
1171                 LM_SHMEM_READ(pdev, offset, &val);
1172                 max_iscsi_cons[port] = lm_parse_license_info_bounded(val, MAX_CONNECTIONS_ISCSI,TRUE);
1173                 DbgMessage(pdev, INFORMi, "max_iscsi_conn from shmem %d for port %d\n",val, port);
1174                 /* FCOE */
1175                 offset = OFFSETOF(shmem_region_t, drv_lic_key[port].max_fcoe_init_conn) & 0xfffffffc;
1176                 LM_SHMEM_READ(pdev, offset, &val);
1177                 if(0 == lm_parse_license_info(val,TRUE))
1178                 {
1179                     max_fcoe_cons[port] = 0;
1180                 }
1181                 else
1182                 {
1183                     max_fcoe_cons[port] = MAX_CONNECTIONS_FCOE;
1184                 }
1185                 DbgMessage(pdev, INFORMi, "max_fcoe_conn from shmem %d for port %d\n",val, port);
1186 
1187             }
1188             else
1189             {
1190                 // In case MCP is enabled and there is no licence => there should be no offload connection.
1191                 max_toe_cons[port]      = MAX_CONNECTIONS_TOE_NO_LICENSE;
1192                 max_rdma_cons[port]     = MAX_CONNECTIONS_ISCSI_NO_LICENSE;
1193                 max_iscsi_cons[port]    = MAX_CONNECTIONS_RDMA_NO_LICENSE;
1194                 max_fcoe_cons[port]     = MAX_CONNECTIONS_FCOE_NO_LICENSE;
1195             }
1196             if (CHIP_IS_E1x(pdev))
1197             {
1198                 max_eth_cons[port] = MAX_ETH_REG_CONS;
1199             }
1200             else
1201             {
1202                 max_eth_cons[port] = MAX_CONNECTIONS_VF;
1203             }
1204 
1205             /* get the bar size... unless it's current port and then we have it. otherwise, read from shmem W.C which
1206              * is what the other ports asked for, they could have gotten less, but we're looking into the worst case. */
1207             if (PORT_ID(pdev) == port)
1208             {
1209                 max_bar_supported_cons[port] = pdev->hw_info.bar_size[BAR_1] / LM_DQ_CID_SIZE;
1210             }
1211             else
1212             {
1213                 LM_SHMEM_READ(pdev, OFFSETOF(shmem_region_t, dev_info.port_feature_config[port].config), &val);
1214                 val = (val & PORT_FEAT_CFG_BAR2_SIZE_MASK) >> PORT_FEAT_CFG_BAR2_SIZE_SHIFT;
1215                 if (val != 0)
1216                  {
1217                     /* bit 1 stand for 64K each bit multiply it by two */
1218                     val = (0x40 << ((val - 1)))*0x400;
1219                 }
1220                 max_bar_supported_cons[port] = val / LM_DQ_CID_SIZE;
1221             }
1222         }
1223         else
1224         {
1225             // MCP_WA
1226             LM_SHMEM_READ(pdev, NO_MCP_WA_VALID_LIC_ADDR+4*port, &val);
1227 
1228             if (val == NO_MCP_WA_VALID_LIC_MAGIC)
1229             {
1230                 LM_SHMEM_READ(pdev, NO_MCP_WA_TOE_LIC+4*port, &val);
1231                 max_toe_cons[port] = val;
1232                 LM_SHMEM_READ(pdev, NO_MCP_WA_ISCSI_LIC+4*port, &val);
1233                 max_iscsi_cons[port] = val;
1234                 LM_SHMEM_READ(pdev, NO_MCP_WA_RDMA_LIC+4*port, &val);
1235                 max_rdma_cons[port] = val;
1236 
1237                 /* FCOE */
1238                 // For backward compatibility, same value if it will be required we can add NO_MCP_WA_FCOE_LIC
1239                 max_fcoe_cons[port] = MAX_CONNECTIONS_FCOE_NO_MCP;
1240                 // Fcoe licencing isn't supported.
1241                 /*
1242                 LM_SHMEM_READ(pdev, NO_MCP_WA_FCOE_LIC+4*port, &val);
1243                 max_fcoe_cons[port] = val;
1244                 */
1245             }
1246             else
1247             {
1248                 #ifdef VF_INVOLVED
1249                 max_toe_cons[port] = DEFAULT_CONNECTIONS_TOE - 100;
1250                 #else
1251                 max_toe_cons[port] = DEFAULT_CONNECTIONS_TOE;
1252                 #endif
1253                 max_iscsi_cons[port] = MAX_CONNECTIONS_ISCSI;
1254                 max_rdma_cons[port]  = MAX_CONNECTIONS_RDMA;
1255                 // Need to review this value seems like we take in this case the max value
1256                 max_fcoe_cons[port] = MAX_CONNECTIONS_FCOE_NO_MCP;
1257             }
1258             if (CHIP_IS_E1x(pdev))
1259             {
1260                 max_eth_cons[port] = MAX_ETH_REG_CONS;
1261             }
1262             else
1263             {
1264                 max_eth_cons[port] = MAX_CONNECTIONS_VF;
1265             }
1266             /* For MCP - WA, we always assume the same bar size for all ports: makes life simpler... */
1267             max_bar_supported_cons[port] = pdev->hw_info.bar_size[BAR_1] / LM_DQ_CID_SIZE;
1268         }
1269         /* so after all this - what is the maximum number of connections supported for this port? */
1270         max_supported_cons[port] = log2_align(max_toe_cons[port] + max_rdma_cons[port] + max_iscsi_cons[port] + max_fcoe_cons[port] + max_eth_cons[port]);
1271         max_supported_cons[port] = min(max_supported_cons[port], max_bar_supported_cons[port]);
1272 
1273         /* And after all this... in lediag  / ediag... we assume a maximum of 1024 connections */
1274         #if defined(DOS) || defined(__LINUX)
1275         max_supported_cons[port] = min(max_supported_cons[port], (u32_t)1024);
1276         #endif
1277 
1278         if (max_supported_cons[port] > pdev->hw_info.max_common_conns)
1279         {
1280             pdev->hw_info.max_common_conns = max_supported_cons[port];
1281         }
1282 
1283 
1284     }
1285     /* Now, port specific... */
1286     port = PORT_ID(pdev);
1287     /* now, there could be a problem where the bar limited us, and the max-connections is smaller than the total above, in this case we need to decrease the
1288      * numbers relatively... can't touch MAX_ETH_CONS... */
1289     if (ERR_IF(max_supported_cons[port] < max_eth_cons[port]))
1290     {
1291         return LM_STATUS_INVALID_PARAMETER;
1292     }
1293     if ((max_iscsi_cons[port]  + max_rdma_cons[port] +  max_toe_cons[port] + max_fcoe_cons[port] + max_eth_cons[port]) > max_supported_cons[port])
1294     {
1295         /* we first try giving iscsi + rdma what they asked for... */
1296         if ((max_iscsi_cons[port] + max_rdma_cons[port] + max_fcoe_cons[port] + max_eth_cons[port]) > max_supported_cons[port])
1297         {
1298             u32_t s = max_iscsi_cons[port] + max_rdma_cons[port] +  max_toe_cons[port] + max_fcoe_cons[port]; /* eth out of the game... */
1299             u32_t t = max_supported_cons[port] - pdev->params.max_eth_including_vfs_conns; /* what we want to reach... */
1300             /* relatively decrease all... (x+y+z=s, actual = t: xt/s+yt/s+zt/s = t) */
1301             max_iscsi_cons[port] *=t;
1302             max_iscsi_cons[port] /=s;
1303             max_rdma_cons[port]  *=t;
1304             max_rdma_cons[port]  /=s;
1305             max_toe_cons[port]   *=t;
1306             max_toe_cons[port]   /=s;
1307             max_fcoe_cons[port]  *=t;
1308             max_fcoe_cons[port]  /=s;
1309         }
1310         else
1311          {
1312             /* just give toe what's left... */
1313             max_toe_cons[port] = max_supported_cons[port] - (max_iscsi_cons[port] + max_rdma_cons[port]  + max_fcoe_cons[port] + max_eth_cons[port]);
1314         }
1315     }
1316     if (ERR_IF((max_iscsi_cons[port]  + max_rdma_cons[port] + max_fcoe_cons[port] + max_toe_cons[port] + max_eth_cons[port]) > max_supported_cons[port]))
1317     {
1318         return LM_STATUS_INVALID_PARAMETER;
1319     }
1320 
1321     /* Now lets save our port-specific variables. By this stage we have the maximum supported connections for our port. */
1322     pdev->hw_info.max_port_toe_conn = max_toe_cons[port];
1323     DbgMessage(pdev, INFORMi, "max_toe_conn from shmem %d\n",pdev->hw_info.max_port_toe_conn);
1324     /* RDMA */
1325     pdev->hw_info.max_port_rdma_conn = max_rdma_cons[port];
1326     DbgMessage(pdev, INFORMi, "max_rdma_conn from shmem %d\n",pdev->hw_info.max_port_rdma_conn);
1327     /* ISCSI */
1328     pdev->hw_info.max_port_iscsi_conn = max_iscsi_cons[port];
1329     DbgMessage(pdev, INFORMi, "max_iscsi_conn from shmem %d\n",pdev->hw_info.max_port_iscsi_conn);
1330     /* FCOE */
1331     pdev->hw_info.max_port_fcoe_conn = max_fcoe_cons[port];
1332     DbgMessage(pdev, INFORMi, "max_fcoe_conn from shmem %d\n",pdev->hw_info.max_port_fcoe_conn);
1333 
1334     pdev->hw_info.max_port_conns = log2_align(pdev->hw_info.max_port_toe_conn +
1335                                               pdev->hw_info.max_port_rdma_conn + pdev->hw_info.max_port_iscsi_conn
1336                                               + pdev->hw_info.max_port_fcoe_conn + pdev->params.max_eth_including_vfs_conns);
1337 
1338     if (ERR_IF(pdev->hw_info.max_port_conns > max_bar_supported_cons[port]))
1339     {
1340         /* this would mean an error in the calculations above. */
1341         return LM_STATUS_INVALID_PARAMETER;
1342     }
1343 
1344     return LM_STATUS_SUCCESS;
1345 }
lm_check_valid_mf_cfg(lm_device_t * pdev)1346 static lm_status_t lm_check_valid_mf_cfg(lm_device_t *pdev)
1347 {
1348     lm_hardware_mf_info_t *mf_info    = &pdev->hw_info.mf_info;
1349     lm_status_t           lm_status   = LM_STATUS_SUCCESS;
1350     const u8_t            func_id     = FUNC_ID(pdev);
1351     u8_t                  i           = 0;
1352     u8_t                  j           = 0;
1353     u32_t                 mf_cfg1     = 0;
1354     u32_t                 mf_cfg2     = 0;
1355     u32_t                 ovlan1      = 0;
1356     u32_t                 ovlan2      = 0;
1357     u32_t                 dynamic_cfg = 0;
1358 
1359     /* hard coded offsets in vnic_cfg.tcl. if assertion here fails,
1360      * need to fix vnic_cfg.tcl script as well. */
1361 //    ASSERT_STATIC(OFFSETOF(shmem_region_t,mf_cfg)            == 0x7e4);
1362     ASSERT_STATIC(OFFSETOF(mf_cfg_t,shared_mf_config.clp_mb) == 0);
1363   //ASSERT_STATIC(MCP_CLP_MB_NO_CLP                          == 0x80000000); not yet defined
1364     ASSERT_STATIC(OFFSETOF(mf_cfg_t,func_mf_config)          == 36);
1365     ASSERT_STATIC(OFFSETOF(func_mf_cfg_t,config)             == 0);
1366     ASSERT_STATIC(FUNC_MF_CFG_FUNC_HIDE                      == 0x1);
1367     ASSERT_STATIC(FUNC_MF_CFG_PROTOCOL_ETHERNET_WITH_RDMA    == 0x4);
1368     ASSERT_STATIC(FUNC_MF_CFG_FUNC_DISABLED                  == 0x8);
1369     ASSERT_STATIC(OFFSETOF(func_mf_cfg_t,mac_upper)          == 4);
1370     ASSERT_STATIC(OFFSETOF(func_mf_cfg_t,mac_lower)          == 8);
1371     ASSERT_STATIC(FUNC_MF_CFG_UPPERMAC_DEFAULT               == 0x0000ffff);
1372     ASSERT_STATIC(FUNC_MF_CFG_LOWERMAC_DEFAULT               == 0xffffffff);
1373     ASSERT_STATIC(OFFSETOF(func_mf_cfg_t,e1hov_tag)          == 12);
1374     ASSERT_STATIC(FUNC_MF_CFG_E1HOV_TAG_DEFAULT              == 0x0000ffff);
1375     ASSERT_STATIC(sizeof(func_mf_cfg_t)                      == 24);
1376 
1377     /* trace mf cfg parameters */
1378     DbgMessage(pdev, INFORMi, "MF cfg parameters for function %d:\n", func_id);
1379     DbgMessage(pdev, INFORMi, "\t func_mf_cfg=0x%x\n\t multi_vnics_mode=%d\n\t vnics_per_port=%d\n\t ovlan/vifid=%d\n\t min_bw=%d\n\t max_bw=%d\n",
1380                 mf_info->func_mf_cfg,
1381                 mf_info->vnics_per_port,
1382                 mf_info->multi_vnics_mode,
1383                 mf_info->ext_id,
1384                 mf_info->min_bw,
1385                 mf_info->max_bw);
1386     DbgMessage(pdev, INFORMi, "\t mac addr (overiding main and iscsi): %02x %02x %02x %02x %02x %02x\n",
1387             pdev->hw_info.mac_addr[0],
1388             pdev->hw_info.mac_addr[1],
1389             pdev->hw_info.mac_addr[2],
1390             pdev->hw_info.mac_addr[3],
1391             pdev->hw_info.mac_addr[4],
1392             pdev->hw_info.mac_addr[5]);
1393 
1394     /* verify that function is not hidden */
1395     if (GET_FLAGS(mf_info->func_mf_cfg, FUNC_MF_CFG_FUNC_HIDE))
1396     {
1397         DbgMessage(pdev, FATAL, "Enumerated function %d, is marked as hidden\n", func_id);
1398         lm_status = LM_STATUS_FAILURE;
1399         goto _end;
1400     }
1401 
1402     if (mf_info->vnics_per_port > 1 && !mf_info->multi_vnics_mode)
1403     {
1404         DbgMessage(pdev, FATAL, "invalid mf mode configuration: vnics_per_port=%d, multi_vnics_mode=%d\n",
1405                     mf_info->vnics_per_port,
1406                     mf_info->multi_vnics_mode);
1407         lm_status = LM_STATUS_FAILURE;
1408         //DbgBreakIf(1);
1409         goto _end;
1410     }
1411 
1412     /* Sanity checks on outer-vlan for switch_dependent_mode... */
1413     if (mf_info->mf_mode == MULTI_FUNCTION_SD)
1414     {
1415         /* enumerated vnic id > 0 must have valid ovlan if we're in switch-dependet mode */
1416         if ((VNIC_ID(pdev) > 0) && !VALID_OVLAN(OVLAN(pdev)))
1417         {
1418             DbgMessage(pdev, WARNi, "invalid mf mode configuration: VNICID=%d, Function is enumerated, ovlan (%d) is invalid\n",
1419                         VNIC_ID(pdev), OVLAN(pdev));
1420 #ifdef EDIAG
1421             // Allow OVLAN 0xFFFF in ediag UFP mode
1422             if (mf_info->sd_mode != SD_UFP_MODE)
1423             {
1424                 lm_status = LM_STATUS_FAILURE;
1425             }
1426 #else
1427             lm_status = LM_STATUS_FAILURE;
1428 #endif
1429             goto _end;
1430         }
1431 
1432         /* additional sanity checks */
1433         if (!VALID_OVLAN(OVLAN(pdev)) && mf_info->multi_vnics_mode)
1434         {
1435             DbgMessage(pdev, FATAL, "invalid mf mode configuration: multi_vnics_mode=%d, ovlan=%d\n",
1436                         mf_info->multi_vnics_mode,
1437                         OVLAN(pdev));
1438 #ifdef EDIAG
1439             // Allow OVLAN 0xFFFF in ediag UFP mode
1440             if (mf_info->sd_mode != SD_UFP_MODE)
1441             {
1442                 lm_status = LM_STATUS_FAILURE;
1443             }
1444 #else
1445             lm_status = LM_STATUS_FAILURE;
1446 #endif
1447             goto _end;
1448         }
1449         /* verify all functions are either mf mode or sf mode:
1450          * if we set mode to mf, make sure that all non hidden functions have valid ovlan
1451          * if we set mode to sf, make sure that all non hidden functions have invalid ovlan */
1452         LM_FOREACH_ABS_FUNC_IN_PORT(pdev, i)
1453         {
1454             LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[i].config),&mf_cfg1);
1455             LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[i].e1hov_tag), &ovlan1);
1456             if (!GET_FLAGS(mf_cfg1, FUNC_MF_CFG_FUNC_HIDE) &&
1457                 (((mf_info->multi_vnics_mode) && !VALID_OVLAN(ovlan1)) ||
1458                  ((!mf_info->multi_vnics_mode) && VALID_OVLAN(ovlan1))))
1459             {
1460 #ifdef EDIAG
1461 				// Allow OVLAN 0xFFFF in eDiag UFP mode
1462                 if (mf_info->sd_mode != SD_UFP_MODE)
1463                 {
1464 	                lm_status = LM_STATUS_FAILURE;
1465                 }
1466 #else
1467 		lm_status= LM_STATUS_FAILURE;
1468 #endif
1469                 goto _end;
1470             }
1471         }
1472         /* verify different ovlan between funcs on same port */
1473         LM_FOREACH_ABS_FUNC_IN_PORT(pdev, i)
1474         {
1475             LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[i].config),&mf_cfg1);
1476             LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[i].e1hov_tag), &ovlan1);
1477             /* iterate from the next function in the port till max func */
1478             for (j = i + 2; j < E1H_FUNC_MAX; j += 2)
1479             {
1480                 LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[j].config),&mf_cfg2);
1481                 LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[j].e1hov_tag), &ovlan2);
1482                 if (!GET_FLAGS(mf_cfg1, FUNC_MF_CFG_FUNC_HIDE) && VALID_OVLAN(ovlan1) &&
1483                     !GET_FLAGS(mf_cfg2, FUNC_MF_CFG_FUNC_HIDE) && VALID_OVLAN(ovlan2) &&
1484                     (ovlan1 == ovlan2) )
1485                 {
1486                     lm_status = LM_STATUS_FAILURE;
1487                     DbgBreakIf(1);
1488                     goto _end;
1489                 }
1490             }
1491         }
1492         // Check if DCC is active (Debugging only)
1493         LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, port_mf_config[PATH_ID(pdev)][PORT_ID(pdev)].dynamic_cfg),&dynamic_cfg );
1494         if( PORT_MF_CFG_E1HOV_TAG_DEFAULT == ( dynamic_cfg & PORT_MF_CFG_E1HOV_TAG_MASK ) )
1495         {
1496             pdev->hw_info.is_dcc_active = FALSE;
1497         }
1498         else
1499         {
1500             pdev->hw_info.is_dcc_active = TRUE;
1501         }
1502     } // MULTI_FUNCTION_SD
1503 _end:
1504     return lm_status;
1505 }
1506 
lm_cmng_get_shmem_info(lm_device_t * pdev)1507 void lm_cmng_get_shmem_info( lm_device_t* pdev )
1508 {
1509     u32_t                  val     = 0;
1510     u8_t                   i       = 0;
1511     u8_t                   vnic    = 0;
1512     lm_hardware_mf_info_t *mf_info = &pdev->hw_info.mf_info;;
1513 
1514     if( !IS_MF_MODE_CAPABLE(pdev) )
1515     {
1516         DbgBreakIf(1) ;
1517         return;
1518     }
1519 
1520     LM_FOREACH_ABS_FUNC_IN_PORT(pdev, i)
1521     {
1522         LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[i].config),&val);
1523         /* get min/max bw */
1524         mf_info->min_bw[vnic] = (GET_FLAGS(val, FUNC_MF_CFG_MIN_BW_MASK) >> FUNC_MF_CFG_MIN_BW_SHIFT);
1525         mf_info->max_bw[vnic] = (GET_FLAGS(val, FUNC_MF_CFG_MAX_BW_MASK) >> FUNC_MF_CFG_MAX_BW_SHIFT);
1526         vnic++;
1527     }
1528 }
1529 
1530 /**lm_get_vnics_per_port
1531  * Get the value of vnics_per_port according to the MF mode and
1532  * port mode.
1533  *
1534  * Note: This function assumes that multi_vnics_mode and
1535  * chip_port_mode are initialized in hw_info.
1536  *
1537  * @param pdev
1538  *
1539  * @return u8_t the value of vnics_per_port for this pdev's port
1540  *         mode and MF mode. This value does not consider hidden
1541  *         PFs.
1542  */
lm_get_vnics_per_port(lm_device_t * pdev)1543 static u8_t lm_get_vnics_per_port(lm_device_t* pdev)
1544 {
1545     if (pdev->hw_info.mf_info.multi_vnics_mode)
1546     {
1547         return LM_PFS_PER_PORT(pdev);
1548     }
1549     else
1550     {
1551         return 1;
1552     }
1553 }
1554 
1555 /* Get shmem multi function config info for switch dependent mode */
lm_get_shmem_mf_cfg_info_sd(lm_device_t * pdev)1556 static lm_status_t lm_get_shmem_mf_cfg_info_sd(lm_device_t *pdev)
1557 {
1558     lm_hardware_mf_info_t *mf_info = &pdev->hw_info.mf_info;
1559     u32_t                  val     = 0;
1560 
1561     /* get ovlan if we're in switch-dependent mode... */
1562     LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[ABS_FUNC_ID(pdev)].e1hov_tag),&val);
1563     mf_info->ext_id = (u16_t)val;
1564 
1565     mf_info->multi_vnics_mode = 1;
1566     if(!VALID_OVLAN(OVLAN(pdev)))
1567     {
1568         /* Unexpected at this time */
1569         DbgMessage(pdev, FATAL, "Invalid mf mode configuration: VNICID=%d, Function is enumerated, ovlan (%d) is invalid\n",
1570                    VNIC_ID(pdev), OVLAN(pdev));
1571 #ifdef EDIAG
1572      	// Allow OVLAN 0xFFFF in ediag UFP mode
1573      	if (mf_info->sd_mode != SD_UFP_MODE)
1574      	{
1575           	return LM_STATUS_FAILURE;
1576      	}
1577 #else
1578         return LM_STATUS_FAILURE;
1579 #endif
1580     }
1581 
1582     /* Get capabilities */
1583     if (GET_FLAGS(mf_info->func_mf_cfg, FUNC_MF_CFG_PROTOCOL_MASK) == FUNC_MF_CFG_PROTOCOL_ISCSI)
1584     {
1585         pdev->params.mf_proto_support_flags |= LM_PROTO_SUPPORT_ISCSI;
1586     }
1587     else if (GET_FLAGS(mf_info->func_mf_cfg, FUNC_MF_CFG_PROTOCOL_MASK) == FUNC_MF_CFG_PROTOCOL_FCOE)
1588     {
1589         pdev->params.mf_proto_support_flags |= LM_PROTO_SUPPORT_FCOE;
1590     }
1591     else
1592     {
1593         pdev->params.mf_proto_support_flags |= LM_PROTO_SUPPORT_ETHERNET;
1594     }
1595 
1596     mf_info->vnics_per_port = lm_get_vnics_per_port(pdev);
1597 
1598     return LM_STATUS_SUCCESS;
1599 }
1600 
1601 
1602 /* Get shmem multi function config info for switch dependent mode */
lm_get_shmem_mf_cfg_info_sd_bd(lm_device_t * pdev)1603 static lm_status_t lm_get_shmem_mf_cfg_info_sd_bd(lm_device_t *pdev)
1604 {
1605     lm_status_t lm_status = lm_get_shmem_mf_cfg_info_sd(pdev);
1606 
1607     return lm_status;
1608 }
1609 
1610 
1611 /* Get shmem multi function config info for switch dependent mode */
lm_get_shmem_mf_cfg_info_sd_ufp(lm_device_t * pdev)1612 static lm_status_t lm_get_shmem_mf_cfg_info_sd_ufp(lm_device_t *pdev)
1613 {
1614     lm_status_t lm_status = lm_get_shmem_mf_cfg_info_sd(pdev);
1615 
1616     return lm_status;
1617 }
1618 
_copy_mac_upper_lower_to_arr(IN u32_t mac_upper,IN u32_t mac_lower,OUT u8_t * mac_addr)1619 static void _copy_mac_upper_lower_to_arr(IN u32_t mac_upper, IN u32_t mac_lower, OUT u8_t* mac_addr)
1620 {
1621     if(mac_addr)
1622     {
1623         mac_addr[0] = (u8_t) (mac_upper >> 8);
1624         mac_addr[1] = (u8_t) mac_upper;
1625         mac_addr[2] = (u8_t) (mac_lower >> 24);
1626         mac_addr[3] = (u8_t) (mac_lower >> 16);
1627         mac_addr[4] = (u8_t) (mac_lower >> 8);
1628         mac_addr[5] = (u8_t) mac_lower;
1629     }
1630 }
1631 
lm_get_shmem_ext_mac_addresses(lm_device_t * pdev)1632 static void lm_get_shmem_ext_mac_addresses(lm_device_t *pdev)
1633 {
1634     u32_t      mac_upper   = 0;
1635     u32_t      mac_lower   = 0;
1636     u32_t      offset      = 0;
1637     const u8_t abs_func_id = ABS_FUNC_ID(pdev);
1638 
1639     /* We have a different mac address per iscsi / fcoe - we'll set it from extended multi function info, but only if it's valid, otherwise
1640      * we'll leave the same mac as for L2
1641      */
1642     offset = OFFSETOF(mf_cfg_t, func_ext_config[abs_func_id].iscsi_mac_addr_upper);
1643     LM_MFCFG_READ(pdev, offset, &mac_upper);
1644 
1645     offset = OFFSETOF(mf_cfg_t, func_ext_config[abs_func_id].iscsi_mac_addr_lower);
1646     LM_MFCFG_READ(pdev, offset, &mac_lower);
1647 
1648     _copy_mac_upper_lower_to_arr(mac_upper, mac_lower, pdev->hw_info.iscsi_mac_addr);
1649 
1650     offset = OFFSETOF(mf_cfg_t, func_ext_config[abs_func_id].fcoe_mac_addr_upper);
1651     LM_MFCFG_READ(pdev, offset, &mac_upper);
1652 
1653     offset = OFFSETOF(mf_cfg_t, func_ext_config[abs_func_id].fcoe_mac_addr_lower);
1654     LM_MFCFG_READ(pdev, offset, &mac_lower);
1655 
1656     _copy_mac_upper_lower_to_arr(mac_upper, mac_lower, pdev->hw_info.fcoe_mac_addr);
1657 
1658     offset = OFFSETOF(mf_cfg_t, func_ext_config[abs_func_id].fcoe_wwn_port_name_upper);
1659     LM_MFCFG_READ(pdev, offset, &mac_upper);
1660 
1661     offset = OFFSETOF(mf_cfg_t, func_ext_config[abs_func_id].fcoe_wwn_port_name_lower);
1662     LM_MFCFG_READ(pdev, offset, &mac_lower);
1663 
1664     _copy_mac_upper_lower_to_arr(mac_upper, mac_lower, &(pdev->hw_info.fcoe_wwn_port_name[2]));
1665     pdev->hw_info.fcoe_wwn_port_name[0] = (u8_t) (mac_upper >> 24);
1666     pdev->hw_info.fcoe_wwn_port_name[1] = (u8_t) (mac_upper >> 16);
1667 
1668     offset = OFFSETOF(mf_cfg_t, func_ext_config[abs_func_id].fcoe_wwn_node_name_upper);
1669     LM_MFCFG_READ(pdev, offset, &mac_upper);
1670 
1671     offset = OFFSETOF(mf_cfg_t, func_ext_config[abs_func_id].fcoe_wwn_node_name_lower);
1672     LM_MFCFG_READ(pdev, offset, &mac_lower);
1673 
1674     _copy_mac_upper_lower_to_arr(mac_upper, mac_lower, &(pdev->hw_info.fcoe_wwn_node_name[2]));
1675     pdev->hw_info.fcoe_wwn_node_name[0] = (u8_t) (mac_upper >> 24);
1676     pdev->hw_info.fcoe_wwn_node_name[1] = (u8_t) (mac_upper >> 16);
1677 }
1678 
1679 static u32_t
lm_get_shmem_ext_proto_support_flags(lm_device_t * pdev)1680 lm_get_shmem_ext_proto_support_flags(lm_device_t *pdev)
1681 {
1682     u32_t   func_ext_cfg        = 0;
1683     u32_t   proto_support_flags = 0;
1684 
1685     LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_ext_config[ABS_FUNC_ID(pdev)].func_cfg),&func_ext_cfg);
1686 
1687     if (GET_FLAGS(func_ext_cfg, MACP_FUNC_CFG_FLAGS_ENABLED ))
1688     {
1689         if (GET_FLAGS(func_ext_cfg, MACP_FUNC_CFG_FLAGS_ETHERNET))
1690         {
1691             proto_support_flags |= LM_PROTO_SUPPORT_ETHERNET;
1692         }
1693         if (GET_FLAGS(func_ext_cfg, MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD))
1694         {
1695             proto_support_flags |= LM_PROTO_SUPPORT_ISCSI;
1696         }
1697         if (GET_FLAGS(func_ext_cfg, MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD))
1698         {
1699             proto_support_flags |= LM_PROTO_SUPPORT_FCOE;
1700         }
1701     }
1702 
1703     return proto_support_flags;
1704 }
1705 
1706 /* Get shmem multi function config info for switch independent mode */
lm_get_shmem_mf_cfg_info_si(lm_device_t * pdev)1707 static lm_status_t lm_get_shmem_mf_cfg_info_si(lm_device_t *pdev)
1708 {
1709     lm_hardware_mf_info_t *mf_info = &pdev->hw_info.mf_info;
1710     u32_t val       = 0;
1711 
1712     /* No outer-vlan... we're in switch-independent mode, so if the mac is valid - assume multi-function */
1713     LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_ext_config[ABS_FUNC_ID(pdev)].func_cfg),&val);
1714     val = val & MACP_FUNC_CFG_FLAGS_MASK;
1715     mf_info->multi_vnics_mode = (val != 0);
1716     mf_info->path_has_ovlan = FALSE;
1717 
1718     pdev->params.mf_proto_support_flags = lm_get_shmem_ext_proto_support_flags(pdev);
1719 
1720     mf_info->vnics_per_port = lm_get_vnics_per_port(pdev);
1721 
1722     return LM_STATUS_SUCCESS;
1723 
1724 }
1725 
lm_get_shmem_mf_cfg_info_niv(lm_device_t * pdev)1726 lm_status_t lm_get_shmem_mf_cfg_info_niv(lm_device_t *pdev)
1727 {
1728     lm_hardware_mf_info_t   *mf_info     = &pdev->hw_info.mf_info;
1729     u32_t                   func_config  = 0;
1730     u32_t                   niv_config   = 0;
1731     u32_t                   e1hov_tag    = 0;
1732 
1733     mf_info->multi_vnics_mode = TRUE;
1734 
1735     LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[ABS_FUNC_ID(pdev)].e1hov_tag),&e1hov_tag);
1736     LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[ABS_FUNC_ID(pdev)].config), &func_config);
1737     LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[ABS_FUNC_ID(pdev)].afex_config), &niv_config);
1738 
1739     mf_info->ext_id = (u16_t)(GET_FLAGS(e1hov_tag, FUNC_MF_CFG_E1HOV_TAG_MASK)>>FUNC_MF_CFG_E1HOV_TAG_SHIFT);
1740     mf_info->default_vlan = (u16_t)(GET_FLAGS(e1hov_tag, FUNC_MF_CFG_AFEX_VLAN_MASK)>>FUNC_MF_CFG_AFEX_VLAN_SHIFT);
1741 
1742     mf_info->niv_allowed_priorities = (u8_t)(GET_FLAGS(niv_config, FUNC_MF_CFG_AFEX_COS_FILTER_MASK)>>FUNC_MF_CFG_AFEX_COS_FILTER_SHIFT);
1743     mf_info->niv_default_cos = (u8_t)(GET_FLAGS(func_config, FUNC_MF_CFG_TRANSMIT_PRIORITY_MASK)>>FUNC_MF_CFG_TRANSMIT_PRIORITY_SHIFT);
1744     mf_info->afex_vlan_mode = GET_FLAGS(niv_config, FUNC_MF_CFG_AFEX_VLAN_MODE_MASK)>>FUNC_MF_CFG_AFEX_VLAN_MODE_SHIFT;
1745     mf_info->niv_mba_enabled = GET_FLAGS(niv_config, FUNC_MF_CFG_AFEX_MBA_ENABLED_MASK)>>FUNC_MF_CFG_AFEX_MBA_ENABLED_SHIFT;
1746 
1747 
1748     pdev->params.mf_proto_support_flags = lm_get_shmem_ext_proto_support_flags(pdev);
1749 
1750     mf_info->vnics_per_port = lm_get_vnics_per_port(pdev);
1751 
1752     return LM_STATUS_SUCCESS;
1753 }
1754 
lm_shmem_set_default(lm_device_t * pdev)1755 static lm_status_t lm_shmem_set_default(lm_device_t *pdev)
1756 {
1757     lm_hardware_mf_info_t *mf_info   = &pdev->hw_info.mf_info;
1758     u8_t i;
1759 
1760     /* set defaults: */
1761     mf_info->multi_vnics_mode = 0;
1762     mf_info->vnics_per_port   = 1;
1763     mf_info->ext_id           = 0xffff; /* invalid ovlan */ /* TBD - E1H: - what is the right value for Cisco? */
1764 
1765     ASSERT_STATIC( ARRSIZE(mf_info->min_bw) == ARRSIZE(mf_info->max_bw) )
1766 
1767     for (i = 0; i < ARRSIZE(mf_info->min_bw); i++)
1768     {
1769         mf_info->min_bw[i] = 0;
1770         mf_info->max_bw[i] = 200;
1771     }
1772     pdev->hw_info.shmem_base          = 0;
1773     pdev->hw_info.max_port_toe_conn   = MAX_CONNECTIONS_TOE;
1774     pdev->hw_info.max_port_rdma_conn  = MAX_CONNECTIONS_RDMA;
1775     pdev->hw_info.max_port_iscsi_conn = MAX_CONNECTIONS_ISCSI;
1776     pdev->hw_info.max_port_fcoe_conn  = MAX_CONNECTIONS_FCOE;
1777     pdev->hw_info.max_port_conns      = MAX_CONNECTIONS;
1778     pdev->hw_info.max_common_conns    = MAX_CONNECTIONS;
1779 
1780     return LM_STATUS_SUCCESS;
1781 }
1782 
lm_get_shmem_base_addr(lm_device_t * pdev)1783 static u32_t lm_get_shmem_base_addr(lm_device_t *pdev)
1784 {
1785     u32_t val            = 0;
1786     u32_t min_shmem_addr = 0;
1787     u32_t max_shmem_addr = 0;
1788 
1789     val = REG_RD(pdev,MISC_REG_SHARED_MEM_ADDR);
1790     if (CHIP_IS_E1(pdev))
1791     {
1792         min_shmem_addr = 0xa0000;
1793         max_shmem_addr = 0xb0000;
1794     }
1795     else if (CHIP_IS_E1H(pdev))
1796     {
1797        min_shmem_addr = 0xa0000;
1798        max_shmem_addr = 0xc0000;
1799     }
1800     else if (CHIP_IS_E2E3(pdev))
1801     {
1802         min_shmem_addr = 0x3a0000;
1803         max_shmem_addr = 0x3c8000;
1804     }
1805     else
1806     {
1807         u32 pcicfg_chip;
1808         mm_read_pci(pdev, 0, &pcicfg_chip);
1809         DbgMessage(pdev, FATAL , "Unknown chip 0x%x, pcicfg[0]=0x%x, GRC[0x2000]=0x%x\n",
1810                     CHIP_NUM(pdev), pcicfg_chip, REG_RD(pdev, 0x2000));
1811         DbgBreakMsg("Unknown chip version");
1812     }
1813 
1814     if (val < min_shmem_addr || val >= max_shmem_addr)
1815     {
1816         /* Invalid shmem base address return '0' */
1817         val = 0;
1818     }
1819 
1820     return val;
1821 }
1822 
1823 /**
1824  * @Description
1825  *     This function is called when MCP is not detected. It
1826  *     initializes lmdevice parameters that are required for
1827  *     functional running with default values or values read
1828  *     from vnic_cfg.tcl script.
1829  *
1830  * @param pdev
1831  *
1832  * @return lm_status_t
1833  */
lm_get_shmem_info_no_mcp_bypass(lm_device_t * pdev)1834 static lm_status_t lm_get_shmem_info_no_mcp_bypass(lm_device_t *pdev)
1835 {
1836     lm_hardware_mf_info_t *mf_info = &pdev->hw_info.mf_info;
1837     lm_status_t lm_status          = LM_STATUS_SUCCESS;
1838     u32_t val                      = 0;
1839 
1840 
1841     DbgMessage(pdev, WARN, "MCP Down Detected\n");
1842 #ifndef _VBD_CMD_
1843     val = REG_RD(pdev,MISC_REG_SHARED_MEM_ADDR);
1844     DbgMessage(pdev, FATAL, "FW ShMem addr: 0x%x\n", val);
1845 #endif // _VBD_CMD_
1846 
1847     pdev->hw_info.mcp_detected = 0;
1848     /* should have a magic number written if configuration was set otherwise, use default above */
1849     LM_SHMEM_READ(pdev, NO_MCP_WA_CFG_SET_ADDR, &val);
1850     if (val == NO_MCP_WA_CFG_SET_MAGIC)
1851     {
1852         LM_SHMEM_READ(pdev, NO_MCP_WA_FORCE_5710, &val);
1853         LM_SHMEM_READ(pdev, NO_MCP_WA_MULTI_VNIC_MODE, &val);
1854         mf_info->multi_vnics_mode = (u8_t)val;
1855         if (mf_info->multi_vnics_mode)
1856         {
1857             LM_SHMEM_READ(pdev, NO_MCP_WA_OVLAN(ABS_FUNC_ID(pdev)), &val);
1858             mf_info->ext_id = (u16_t)val;
1859 
1860             mf_info->multi_vnics_mode = VALID_OVLAN(mf_info->ext_id)? 1 : 0;
1861             mf_info->path_has_ovlan = mf_info->multi_vnics_mode;
1862 
1863             /* decide on path multi vnics mode - incase we're not in mf mode...and in 4-port-mode good enough to check vnic-0 of the other port, on the same path */
1864             if ((CHIP_PORT_MODE(pdev) == LM_CHIP_PORT_MODE_4) &&  !mf_info->multi_vnics_mode)
1865             {
1866                 u8_t other_port = !PORT_ID(pdev);
1867                 u8_t abs_func_on_other_port = PATH_ID(pdev) + 2*other_port;
1868                 LM_SHMEM_READ(pdev, NO_MCP_WA_OVLAN(abs_func_on_other_port), &val);
1869 
1870                 mf_info->path_has_ovlan = VALID_OVLAN((u16_t)val) ? 1 : 0;
1871             }
1872 
1873             /* For simplicity, we leave vnics_per_port to be 2, for resource splitting issues... */
1874             if (mf_info->path_has_ovlan)
1875             {
1876                 if (CHIP_PORT_MODE(pdev) == LM_CHIP_PORT_MODE_4)
1877                 {
1878                     mf_info->vnics_per_port = 2;
1879                 }
1880                 else
1881                 {
1882                     mf_info->vnics_per_port = 4;
1883                 }
1884             }
1885 
1886             /* If we're multi-vnic, we'll set a default mf_mode of switch-dependent, this could be overriden
1887              * later on by registry */
1888             mf_info->mf_mode = MULTI_FUNCTION_SD;
1889 
1890         }
1891         lm_status = lm_get_shmem_license_info(pdev);
1892         if (lm_status != LM_STATUS_SUCCESS)
1893         {
1894             return lm_status;
1895         }
1896     }
1897     /* sanity checks on vnic params */
1898     if (mf_info->multi_vnics_mode)
1899     {
1900         if (!VALID_OVLAN(mf_info->ext_id))
1901         {
1902             DbgMessage(pdev, FATAL, "Invalid ovlan (0x%x) configured for Func %d. Can't load the function.\n",
1903                         mf_info->ext_id, ABS_FUNC_ID(pdev));
1904             lm_status = LM_STATUS_FAILURE;
1905         }
1906     }
1907     if ((mf_info->vnics_per_port - 1 < VNIC_ID(pdev)) || ( !mf_info->multi_vnics_mode && (VNIC_ID(pdev) > 0)))
1908     {
1909         DbgMessage(pdev, FATAL, "Invalid vnics_per_port (%d) configured for Func %d. Can't load the function.\n",
1910                     mf_info->vnics_per_port, ABS_FUNC_ID(pdev));
1911         lm_status = LM_STATUS_FAILURE;
1912     }
1913     return lm_status;
1914 }
1915 
1916 
1917 
lm_get_shmem_shared_hw_config(lm_device_t * pdev)1918 static lm_status_t lm_get_shmem_shared_hw_config(lm_device_t *pdev)
1919 {
1920     u32_t val = 0;
1921     u8_t  i   = 0;
1922 
1923     /* Get the hw config words. */
1924     LM_SHMEM_READ(pdev, OFFSETOF(shmem_region_t, dev_info.shared_hw_config.config),&val);
1925     pdev->hw_info.nvm_hw_config = val;
1926     pdev->params.link.hw_led_mode = ((pdev->hw_info.nvm_hw_config & SHARED_HW_CFG_LED_MODE_MASK) >> SHARED_HW_CFG_LED_MODE_SHIFT);
1927     DbgMessage(pdev, INFORMi, "nvm_hw_config %d\n",val);
1928 
1929     LM_SHMEM_READ(pdev,
1930         OFFSETOF(shmem_region_t, dev_info.shared_hw_config.config2),&val);
1931     pdev->hw_info.nvm_hw_config2 = val;
1932     DbgMessage(pdev, INFORMi, "nvm_hw_configs %d\n",val);
1933 
1934     //board_sn;
1935     LM_SHMEM_READ(pdev,
1936         OFFSETOF(shmem_region_t, dev_info.shared_hw_config.part_num),&val);
1937     pdev->hw_info.board_num[0] = (u8_t) val;
1938     pdev->hw_info.board_num[1] = (u8_t) (val >> 8);
1939     pdev->hw_info.board_num[2] = (u8_t) (val >> 16);
1940     pdev->hw_info.board_num[3] = (u8_t) (val >> 24);
1941 
1942     LM_SHMEM_READ(pdev,
1943         OFFSETOF(shmem_region_t, dev_info.shared_hw_config.part_num)+4,&val);
1944     pdev->hw_info.board_num[4] = (u8_t) val;
1945     pdev->hw_info.board_num[5] = (u8_t) (val >> 8);
1946     pdev->hw_info.board_num[6] = (u8_t) (val >> 16);
1947     pdev->hw_info.board_num[7] = (u8_t) (val >> 24);
1948 
1949     LM_SHMEM_READ(pdev,
1950         OFFSETOF(shmem_region_t, dev_info.shared_hw_config.part_num)+8,&val);
1951     pdev->hw_info.board_num[8] = (u8_t) val;
1952     pdev->hw_info.board_num[9] = (u8_t) (val >> 8);
1953     pdev->hw_info.board_num[10] =(u8_t) (val >> 16);
1954     pdev->hw_info.board_num[11] =(u8_t) (val >> 24);
1955 
1956     LM_SHMEM_READ(pdev,
1957         OFFSETOF(shmem_region_t, dev_info.shared_hw_config.part_num)+12,&val);
1958     pdev->hw_info.board_num[12] = (u8_t) val;
1959     pdev->hw_info.board_num[13] = (u8_t) (val >> 8);
1960     pdev->hw_info.board_num[14] = (u8_t) (val >> 16);
1961     pdev->hw_info.board_num[15] = (u8_t) (val >> 24);
1962     DbgMessage(pdev, INFORMi, "board_sn: ");
1963     for (i = 0 ; i < 16 ; i++ )
1964     {
1965         DbgMessage(pdev, INFORMi, "%02x",pdev->hw_info.board_num[i]);
1966     }
1967     DbgMessage(pdev, INFORMi, "\n");
1968 
1969     /* Get the override preemphasis flag */
1970     LM_SHMEM_READ(pdev,OFFSETOF(shmem_region_t,dev_info.shared_feature_config.config),&val);
1971     if GET_FLAGS(val, SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_ENABLED)
1972     {
1973         SET_FLAGS( pdev->params.link.feature_config_flags, ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED);
1974     }
1975     else
1976     {
1977         RESET_FLAGS(pdev->params.link.feature_config_flags,ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED);
1978     }
1979 #ifdef EDIAG
1980     /* Diag doesn't support remote fault detection */
1981     SET_FLAGS( pdev->params.link.feature_config_flags, ELINK_FEATURE_CONFIG_DISABLE_REMOTE_FAULT_DET);
1982     /* Only Diag supports IEEE PHY testing */
1983     SET_FLAGS( pdev->params.link.feature_config_flags, ELINK_FEATURE_CONFIG_IEEE_PHY_TEST);
1984 #endif
1985     return LM_STATUS_SUCCESS;
1986 }
1987 
lm_get_shmem_mf_cfg_base(lm_device_t * pdev)1988 static u32_t lm_get_shmem_mf_cfg_base(lm_device_t *pdev)
1989 {
1990     u32_t shmem2_size;
1991     u32_t offset;
1992     u32_t mf_cfg_offset_value;
1993 
1994     offset = pdev->hw_info.shmem_base + OFFSETOF(shmem_region_t, func_mb) + E1H_FUNC_MAX * sizeof(struct drv_func_mb);
1995     if (pdev->hw_info.shmem_base2 != 0)
1996     {
1997         LM_SHMEM2_READ(pdev, OFFSETOF(shmem2_region_t,size), &shmem2_size);
1998         if (shmem2_size > OFFSETOF(shmem2_region_t,mf_cfg_addr))
1999         {
2000             LM_SHMEM2_READ(pdev, OFFSETOF(shmem2_region_t,mf_cfg_addr), &mf_cfg_offset_value);
2001             if (SHMEM_MF_CFG_ADDR_NONE != mf_cfg_offset_value)
2002             {
2003                 offset = mf_cfg_offset_value;
2004             }
2005         }
2006     }
2007     return offset;
2008 }
2009 
lm_get_shmem_port_hw_config(lm_device_t * pdev)2010 static lm_status_t lm_get_shmem_port_hw_config(lm_device_t *pdev)
2011 {
2012     u32_t val;
2013     const u8_t port = PORT_ID(pdev);
2014 
2015     /* mba features*/
2016     LM_SHMEM_READ(pdev,
2017         OFFSETOF(shmem_region_t,dev_info.port_feature_config[port].mba_config),
2018         &val);
2019     pdev->hw_info.mba_features = (val & PORT_FEATURE_MBA_BOOT_AGENT_TYPE_MASK);
2020     DbgMessage(pdev, INFORMi, "mba_features %d\n",pdev->hw_info.mba_features);
2021     /* mba_vlan_cfg */
2022     LM_SHMEM_READ(pdev,
2023         OFFSETOF(shmem_region_t,dev_info.port_feature_config[port].mba_vlan_cfg),
2024         &val);
2025     pdev->hw_info.mba_vlan_cfg = val ;
2026     DbgMessage(pdev, INFORMi, "mba_vlan_cfg 0x%x\n",pdev->hw_info.mba_vlan_cfg);
2027 
2028     // port_feature_config bits
2029     LM_SHMEM_READ(pdev,
2030         OFFSETOF(shmem_region_t,dev_info.port_feature_config[port].config),
2031         &val);
2032     pdev->hw_info.port_feature_config = val;
2033     DbgMessage(pdev, INFORMi, "port_feature_config 0x%x\n",pdev->hw_info.port_feature_config);
2034 
2035 #ifndef DOS
2036     /* AutogrEEEn settings */
2037     if(val & PORT_FEAT_CFG_AUTOGREEEN_ENABLED) {
2038         SET_FLAGS( pdev->params.link.feature_config_flags, ELINK_FEATURE_CONFIG_AUTOGREEEN_ENABLED);
2039     } else {
2040         RESET_FLAGS( pdev->params.link.feature_config_flags, ELINK_FEATURE_CONFIG_AUTOGREEEN_ENABLED);
2041     }
2042 #endif
2043     /* clc params*/
2044     LM_SHMEM_READ(pdev,OFFSETOF(shmem_region_t,dev_info.port_hw_config[port].speed_capability_mask),&val);
2045     pdev->params.link.speed_cap_mask[0] = val & PORT_HW_CFG_SPEED_CAPABILITY_D0_MASK;
2046     DbgMessage(pdev, INFORMi, "speed_cap_mask1 %d\n",val);
2047 
2048     LM_SHMEM_READ(pdev,OFFSETOF(shmem_region_t,dev_info.port_hw_config[port].speed_capability_mask2),&val);
2049     pdev->params.link.speed_cap_mask[1] = val & PORT_HW_CFG_SPEED_CAPABILITY_D0_MASK;
2050     DbgMessage(pdev, INFORMi, "speed_cap_mask2 %d\n",val);
2051 
2052     /* Get lane swap*/
2053     LM_SHMEM_READ(pdev,OFFSETOF(shmem_region_t,dev_info.port_hw_config[port].lane_config),&val);
2054     pdev->params.link.lane_config = val;
2055     DbgMessage(pdev, INFORMi, "lane_config %d\n",val);
2056 
2057     /*link config  */
2058     LM_SHMEM_READ(pdev,OFFSETOF(shmem_region_t,dev_info.port_feature_config[port].link_config),&val);
2059     pdev->hw_info.link_config[ELINK_INT_PHY] = val;
2060     pdev->params.link.switch_cfg = val & PORT_FEATURE_CONNECTED_SWITCH_MASK;
2061     DbgMessage(pdev, INFORMi, "link config %d\n",val);
2062 
2063     LM_SHMEM_READ(pdev,OFFSETOF(shmem_region_t,dev_info.port_feature_config[port].link_config2),&val);
2064     pdev->hw_info.link_config[ELINK_EXT_PHY1] = val;
2065 
2066     LM_SHMEM_READ(pdev,OFFSETOF(shmem_region_t,dev_info.port_hw_config[port].multi_phy_config),&val);
2067     /* set the initial value to the link params */
2068     pdev->params.link.multi_phy_config = val;
2069     /* save the initial value if we'll want to restore it later */
2070     pdev->hw_info.multi_phy_config = val;
2071     /* check if 10g KR is blocked on this session */
2072     pdev->hw_info.no_10g_kr = FALSE ;
2073 
2074     LM_SHMEM_READ(pdev,OFFSETOF(shmem_region_t,dev_info.port_hw_config[port].default_cfg),&val);
2075     pdev->hw_info.phy_force_kr_enabler = (val & PORT_HW_CFG_FORCE_KR_ENABLER_MASK) ;
2076 
2077     /* If the force KR enabler is on, 10G/20G should have been enabled in the
2078      * nvram as well. If 10G/20G capbility is not set, it means that the MFW
2079      * disabled it and we should set the no_10g_kr flag */
2080     if(( PORT_HW_CFG_FORCE_KR_ENABLER_NOT_FORCED != pdev->hw_info.phy_force_kr_enabler ) &&
2081         ( FALSE == ( pdev->params.link.speed_cap_mask[0] & (PORT_HW_CFG_SPEED_CAPABILITY_D0_10G | PORT_HW_CFG_SPEED_CAPABILITY_D0_20G))) )
2082     {
2083         pdev->hw_info.no_10g_kr = TRUE ;
2084     }
2085 
2086     /* read EEE mode from shmem (original source is NVRAM) */
2087     LM_SHMEM_READ(pdev,OFFSETOF(shmem_region_t,dev_info.port_feature_config[port].eee_power_mode),&val);
2088     pdev->params.link.eee_mode = val & PORT_FEAT_CFG_EEE_POWER_MODE_MASK;
2089     DbgMessage(pdev, INFORMi, "eee_power_mode 0x%x\n", pdev->params.link.eee_mode);
2090 
2091     if ((pdev->params.link.eee_mode & PORT_FEAT_CFG_EEE_POWER_MODE_MASK) != PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED)
2092     {
2093         SET_FLAGS(pdev->params.link.eee_mode,
2094                               ELINK_EEE_MODE_ENABLE_LPI |
2095                               ELINK_EEE_MODE_ADV_LPI);
2096     }
2097 
2098     return LM_STATUS_SUCCESS;
2099 }
2100 
2101 /* Check if other path is in multi_function_mode */
lm_set_path_has_ovlan(lm_device_t * pdev)2102 static void lm_set_path_has_ovlan(lm_device_t *pdev)
2103 {
2104     lm_hardware_mf_info_t *mf_info = &pdev->hw_info.mf_info;
2105     u32_t                  val     = 0;
2106 
2107     mf_info->path_has_ovlan = FALSE;
2108 
2109     if (mf_info->mf_mode == MULTI_FUNCTION_SD)
2110     {
2111         mf_info->path_has_ovlan = TRUE;
2112     }
2113     else if (mf_info->mf_mode == SINGLE_FUNCTION)
2114     {
2115         /* decide on path multi vnics mode - incase we're not in mf mode...and in 4-port-mode good enough to check vnic-0 of the other port, on the same path */
2116         if (CHIP_PORT_MODE(pdev) == LM_CHIP_PORT_MODE_4)
2117         {
2118             u8_t other_port = !PORT_ID(pdev);
2119             u8_t abs_func_on_other_port = PATH_ID(pdev) + 2*other_port;
2120             LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[abs_func_on_other_port].e1hov_tag),&val);
2121 
2122             mf_info->path_has_ovlan = VALID_OVLAN((u16_t)val) ? 1 : 0;
2123         }
2124     }
2125 }
2126 
2127 /**
2128  * @Description
2129  *    Initializes mf mode and data, checks that mf info is valid
2130  *  by checking that MAC address must be legal (check only upper
2131  *    bytes) for  Switch-Independent mode;
2132  *    OVLAN must be legal for Switch-Dependent mode
2133  *
2134  * @param pdev
2135  *
2136  * @return lm_status_t
2137  */
lm_get_shmem_mf_cfg_info(lm_device_t * pdev)2138 lm_status_t lm_get_shmem_mf_cfg_info(lm_device_t *pdev)
2139 {
2140     lm_hardware_mf_info_t *mf_info = &pdev->hw_info.mf_info;
2141     u32_t val                      = 0;
2142     u32_t val2                     = 0;
2143     u32_t mac_upper                = 0;
2144     lm_status_t status = LM_STATUS_SUCCESS;
2145 
2146     /* Set some mf_info defaults */
2147     mf_info->vnics_per_port   = 1;
2148     mf_info->multi_vnics_mode = FALSE;
2149     mf_info->path_has_ovlan   = FALSE;
2150     mf_info->mf_mode          = SINGLE_FUNCTION;
2151     pdev->params.mf_proto_support_flags = 0;
2152 
2153 
2154     /* Get the multi-function-mode value (switch dependent / independent / single-function )  */
2155     LM_SHMEM_READ(pdev,OFFSETOF(shmem_region_t,dev_info.shared_feature_config.config),&val);
2156     val &= SHARED_FEAT_CFG_FORCE_SF_MODE_MASK;
2157 
2158     switch (val)
2159     {
2160     case SHARED_FEAT_CFG_FORCE_SF_MODE_SWITCH_INDEPT:
2161         LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[ABS_FUNC_ID(pdev)].mac_upper),&mac_upper);
2162         /* check for legal mac (upper bytes)*/
2163         if (mac_upper != FUNC_MF_CFG_UPPERMAC_DEFAULT)
2164         {
2165             mf_info->mf_mode = MULTI_FUNCTION_SI;
2166         }
2167         else
2168         {
2169             DbgMessage(pdev, WARNi, "Illegal configuration for switch independent mode\n");
2170         }
2171         DbgBreakIf(CHIP_IS_E1x(pdev));
2172         break;
2173     case SHARED_FEAT_CFG_FORCE_SF_MODE_MF_ALLOWED:
2174     case SHARED_FEAT_CFG_FORCE_SF_MODE_SPIO4:
2175         /* get OV configuration */
2176         LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[ABS_FUNC_ID(pdev)].e1hov_tag),&val);
2177         val &= FUNC_MF_CFG_E1HOV_TAG_MASK;
2178 
2179         if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT)
2180         {
2181             mf_info->mf_mode = MULTI_FUNCTION_SD;
2182             mf_info->sd_mode = SD_REGULAR_MODE;
2183         }
2184         else
2185         {
2186             DbgMessage(pdev, WARNi, "Illegal configuration for switch dependent mode\n");
2187         }
2188         break;
2189     case SHARED_FEAT_CFG_FORCE_SF_MODE_FORCED_SF:
2190         /* We're not in multi-function mode - return with vnics_per_port=1 & multi_vnics_mode = FALSE*/
2191         return LM_STATUS_SUCCESS;
2192     case SHARED_FEAT_CFG_FORCE_SF_MODE_AFEX_MODE:
2193         /* mark mf mode as NIV if MCP version includes NPAR-SD support
2194            and the MAC address is valid.
2195          */
2196         LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[ABS_FUNC_ID(pdev)].mac_upper),&mac_upper);
2197         if ((LM_SHMEM2_HAS(pdev, afex_driver_support)) &&
2198             (mac_upper != FUNC_MF_CFG_UPPERMAC_DEFAULT) )
2199         {
2200             mf_info->mf_mode = MULTI_FUNCTION_AFEX;
2201         }
2202         else
2203         {
2204             DbgMessage(pdev, WARNi, "Illegal configuration for NPAR-SD mode\n");
2205         }
2206         DbgBreakIf(CHIP_IS_E1x(pdev));
2207         break;
2208     case SHARED_FEAT_CFG_FORCE_SF_MODE_BD_MODE:
2209         mf_info->mf_mode = MULTI_FUNCTION_SD;
2210         mf_info->sd_mode = SD_BD_MODE;
2211         DbgMessage(pdev, WARN, "lm_get_shmem_info: SF_MODE_BD_MODE is detected.\n");
2212         break;
2213 
2214     case SHARED_FEAT_CFG_FORCE_SF_MODE_UFP_MODE:
2215         mf_info->mf_mode = MULTI_FUNCTION_SD;
2216         mf_info->sd_mode = SD_UFP_MODE;
2217         DbgMessage(pdev, WARN, "lm_get_shmem_info: SF_MODE_UFP_MODE is detected.\n");
2218         break;
2219 
2220     case SHARED_FEAT_CFG_FORCE_SF_MODE_EXTENDED_MODE:
2221         /* Get extended mf mode value */
2222         LM_SHMEM_READ(pdev, OFFSETOF(shmem_region_t, dev_info.shared_hw_config.config_3),&val);
2223         val2 &= SHARED_HW_CFG_EXTENDED_MF_MODE_MASK;
2224         switch (val2)
2225         {
2226         case SHARED_HW_CFG_EXTENDED_MF_MODE_NPAR1_DOT_5:
2227             mf_info->mf_mode = MULTI_FUNCTION_SI;
2228             break;
2229 
2230         default:
2231             DbgBreakMsg(" Unknown extended mf mode\n");
2232             return LM_STATUS_FAILURE;
2233         }
2234         break;
2235 
2236     default:
2237         DbgBreakMsg(" Unknown mf mode\n");
2238         return LM_STATUS_FAILURE;
2239     }
2240 
2241     /* Set path mf_mode (which could be different than function mf_mode)  */
2242     lm_set_path_has_ovlan(pdev);
2243 
2244     /* Invalid Multi function configuration: */
2245     if (mf_info->mf_mode == SINGLE_FUNCTION)
2246     {
2247         if (VNIC_ID(pdev) >= 1)
2248         {
2249             return LM_STATUS_FAILURE;
2250         }
2251         return LM_STATUS_SUCCESS;
2252     }
2253 
2254     /* Get the multi-function configuration */
2255     LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[ABS_FUNC_ID(pdev)].config),&val);
2256     mf_info->func_mf_cfg = val;
2257 
2258     switch(mf_info->mf_mode)
2259     {
2260         case MULTI_FUNCTION_SD:
2261         {
2262             switch (mf_info->sd_mode)
2263             {
2264                 case SD_REGULAR_MODE:
2265                     status = lm_get_shmem_mf_cfg_info_sd(pdev);
2266                     break;
2267                 case SD_UFP_MODE:
2268                     status = lm_get_shmem_mf_cfg_info_sd_ufp(pdev);
2269                     break;
2270                 case SD_BD_MODE:
2271                     status = lm_get_shmem_mf_cfg_info_sd_bd(pdev);
2272                     break;
2273                 default:
2274                     DbgBreak();
2275             }
2276 
2277             if(status != LM_STATUS_SUCCESS)
2278                 return status;
2279         }
2280         break;
2281         case MULTI_FUNCTION_SI:
2282         {
2283             lm_get_shmem_mf_cfg_info_si(pdev);
2284         }
2285         break;
2286         case MULTI_FUNCTION_AFEX:
2287         {
2288             lm_get_shmem_mf_cfg_info_niv(pdev);
2289         }
2290         break;
2291         default:
2292         {
2293             DbgBreakIfAll(TRUE);
2294             return LM_STATUS_FAILURE;
2295         }
2296     }
2297 
2298     lm_cmng_get_shmem_info(pdev);
2299 
2300     return lm_check_valid_mf_cfg(pdev);
2301 }
2302 
lm_fcoe_set_default_wwns(lm_device_t * pdev)2303 static void lm_fcoe_set_default_wwns(lm_device_t *pdev)
2304 {
2305     /* create default wwns from fcoe mac adress */
2306     mm_memcpy(&(pdev->hw_info.fcoe_wwn_port_name[2]), pdev->hw_info.fcoe_mac_addr, 6);
2307     pdev->hw_info.fcoe_wwn_port_name[0] = 0x20;
2308     pdev->hw_info.fcoe_wwn_port_name[1] = 0;
2309     mm_memcpy(&(pdev->hw_info.fcoe_wwn_node_name[2]), pdev->hw_info.fcoe_mac_addr, 6);
2310     pdev->hw_info.fcoe_wwn_node_name[0] = 0x10;
2311     pdev->hw_info.fcoe_wwn_node_name[1] = 0;
2312 }
2313 
lm_get_shmem_mf_mac_info(lm_device_t * pdev)2314 static lm_status_t lm_get_shmem_mf_mac_info(lm_device_t *pdev)
2315 {
2316     lm_hardware_mf_info_t *mf_info   = &pdev->hw_info.mf_info;
2317     u32_t                  mac_upper = 0;
2318     u32_t                  mac_lower = 0;
2319 
2320     if (mf_info->mf_mode == SINGLE_FUNCTION)
2321     {
2322         return LM_STATUS_FAILURE;
2323     }
2324 
2325     /* Get the permanent L2 MAC address. */
2326     LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[ABS_FUNC_ID(pdev)].mac_upper),&mac_upper);
2327     LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[ABS_FUNC_ID(pdev)].mac_lower),&mac_lower);
2328 
2329 
2330     /* Mac validity is assumed since we already checked it to determine mf_mode. And we assume mf_mode
2331      * is configured correctly when we enter this function. */
2332     SET_FLAGS(mf_info->flags,MF_INFO_VALID_MAC);
2333     _copy_mac_upper_lower_to_arr(mac_upper, mac_lower, pdev->hw_info.mac_addr);
2334 
2335     /* Set iSCSI / FCOE Mac addresses */
2336     switch (mf_info->mf_mode)
2337     {
2338     case MULTI_FUNCTION_SD:
2339         {
2340             // in E1x the ext mac doesn't exists and will cause MCP parity error CQ67469
2341             if ( CHIP_IS_E1x(pdev) || IS_SD_UFP_MODE(pdev) || IS_SD_BD_MODE(pdev))
2342             {
2343                 /* Set all iscsi and fcoe mac addresses the same as network. */
2344                 mm_memcpy(pdev->hw_info.iscsi_mac_addr, pdev->hw_info.mac_addr, 6);
2345                 mm_memcpy(pdev->hw_info.fcoe_mac_addr,  pdev->hw_info.mac_addr, 6);
2346                 break;
2347             }
2348         }
2349 	/* FALLTHROUGH */
2350     case MULTI_FUNCTION_SI:
2351     case MULTI_FUNCTION_AFEX:
2352         lm_get_shmem_ext_mac_addresses(pdev);
2353         break;
2354     }
2355 
2356     return LM_STATUS_SUCCESS;
2357 }
2358 
lm_get_shmem_sf_mac_info(lm_device_t * pdev)2359 static lm_status_t lm_get_shmem_sf_mac_info(lm_device_t *pdev)
2360 {
2361     u32_t val  = 0;
2362     u32_t val2 = 0;
2363 
2364     LM_SHMEM_READ(pdev,
2365                   OFFSETOF(shmem_region_t, dev_info.port_hw_config[PORT_ID(pdev)].mac_upper),&val);
2366     LM_SHMEM_READ(pdev,
2367                   OFFSETOF(shmem_region_t, dev_info.port_hw_config[PORT_ID(pdev)].mac_lower),&val2);
2368     _copy_mac_upper_lower_to_arr(val, val2, pdev->hw_info.mac_addr);
2369 
2370     /* Get iSCSI MAC address. */
2371     LM_SHMEM_READ(pdev,
2372                   OFFSETOF(shmem_region_t,dev_info.port_hw_config[PORT_ID(pdev)].iscsi_mac_upper),&val);
2373     LM_SHMEM_READ(pdev,
2374                   OFFSETOF(shmem_region_t,dev_info.port_hw_config[PORT_ID(pdev)].iscsi_mac_lower),&val2);
2375     _copy_mac_upper_lower_to_arr(val, val2, pdev->hw_info.iscsi_mac_addr);
2376 
2377      /* Get FCoE MAC addresses. */
2378     LM_SHMEM_READ(pdev,
2379                   OFFSETOF(shmem_region_t,dev_info.port_hw_config[PORT_ID(pdev)].fcoe_fip_mac_upper),&val);
2380     LM_SHMEM_READ(pdev,
2381                   OFFSETOF(shmem_region_t,dev_info.port_hw_config[PORT_ID(pdev)].fcoe_fip_mac_lower),&val2);
2382     _copy_mac_upper_lower_to_arr(val, val2, pdev->hw_info.fcoe_mac_addr);
2383 
2384     LM_SHMEM_READ(pdev,
2385                   OFFSETOF(shmem_region_t,dev_info.port_hw_config[PORT_ID(pdev)].fcoe_wwn_port_name_upper),&val);
2386     LM_SHMEM_READ(pdev,
2387                   OFFSETOF(shmem_region_t,dev_info.port_hw_config[PORT_ID(pdev)].fcoe_wwn_port_name_lower),&val2);
2388     _copy_mac_upper_lower_to_arr(val, val2, &(pdev->hw_info.fcoe_wwn_port_name[2]));
2389     pdev->hw_info.fcoe_wwn_port_name[0] = (u8_t) (val >> 24);
2390     pdev->hw_info.fcoe_wwn_port_name[1] = (u8_t) (val >> 16);
2391 
2392     LM_SHMEM_READ(pdev,
2393                   OFFSETOF(shmem_region_t,dev_info.port_hw_config[PORT_ID(pdev)].fcoe_wwn_node_name_upper),&val);
2394     LM_SHMEM_READ(pdev,
2395                   OFFSETOF(shmem_region_t,dev_info.port_hw_config[PORT_ID(pdev)].fcoe_wwn_node_name_lower),&val2);
2396     _copy_mac_upper_lower_to_arr(val, val2, &(pdev->hw_info.fcoe_wwn_node_name[2]));
2397     pdev->hw_info.fcoe_wwn_node_name[0] = (u8_t) (val >> 24);
2398     pdev->hw_info.fcoe_wwn_node_name[1] = (u8_t) (val >> 16);
2399 
2400     DbgMessage(pdev, INFORMi, "main mac addr: %02x %02x %02x %02x %02x %02x\n",
2401         pdev->hw_info.mac_addr[0],
2402         pdev->hw_info.mac_addr[1],
2403         pdev->hw_info.mac_addr[2],
2404         pdev->hw_info.mac_addr[3],
2405         pdev->hw_info.mac_addr[4],
2406         pdev->hw_info.mac_addr[5]);
2407     DbgMessage(pdev, INFORMi, "iSCSI mac addr: %02x %02x %02x %02x %02x %02x\n",
2408         pdev->hw_info.iscsi_mac_addr[0],
2409         pdev->hw_info.iscsi_mac_addr[1],
2410         pdev->hw_info.iscsi_mac_addr[2],
2411         pdev->hw_info.iscsi_mac_addr[3],
2412         pdev->hw_info.iscsi_mac_addr[4],
2413         pdev->hw_info.iscsi_mac_addr[5]);
2414 
2415     return LM_STATUS_SUCCESS;
2416 }
2417 
2418 /* Gets the sriov info from shmem of ALL functions and marks if configuration is assymetric */
lm_get_shmem_sf_sriov_info(lm_device_t * pdev)2419 static void lm_get_shmem_sf_sriov_info(lm_device_t *pdev)
2420 {
2421     const lm_chip_port_mode_t port_mode         = CHIP_PORT_MODE(pdev);
2422     u32_t                     offset            = 0;
2423     u32_t                     val               = 0;
2424     u8_t                      port_max          = (port_mode == LM_CHIP_PORT_MODE_2)? 1 : PORT_MAX;
2425     const u8_t                port              = PORT_ID(pdev);
2426     u8_t                      port_idx          = 0;
2427     u8_t                      sriov_enabled     = 0xff;
2428     u8_t                      sriov_disabled    = 0xff;
2429 
2430     ASSERT_STATIC((FIELD_SIZE(struct shm_dev_info, port_hw_config)/FIELD_SIZE(struct shm_dev_info, port_hw_config[0])) >= max(PORT_MAX,1));
2431 
2432     if (CHIP_IS_E1x(pdev))
2433     {
2434         pdev->hw_info.sriov_info.shmem_num_vfs_in_pf = 0;
2435         pdev->hw_info.sriov_info.b_pf_asymetric_configuration = FALSE;
2436 
2437         return;
2438     }
2439 
2440     for (port_idx = 0; port_idx < port_max; port_idx++)
2441     {
2442         offset = OFFSETOF(shmem_region_t,dev_info.port_hw_config[port_idx].pf_allocation);
2443         LM_SHMEM_READ(pdev, offset, &val);
2444 
2445         val = (val & PORT_HW_CFG_NUMBER_OF_VFS_MASK) >> PORT_HW_CFG_NUMBER_OF_VFS_SHIFT;
2446 
2447         if (0 == val)
2448         {
2449             sriov_disabled = 1;
2450         }
2451         else
2452         {
2453             sriov_enabled = 1;
2454         }
2455 
2456         if (port_idx == port)
2457         {
2458             pdev->hw_info.sriov_info.shmem_num_vfs_in_pf = val;
2459         }
2460     }
2461 
2462 
2463     /* check if assymteric configuration...basically we initialize both params to 0xff, so the only way they can both be
2464      * the same is if one of the ports was enabled and one was disabled... */
2465     if (sriov_disabled == sriov_enabled)
2466     {
2467         pdev->hw_info.sriov_info.b_pf_asymetric_configuration = TRUE;
2468     }
2469     else
2470     {
2471         pdev->hw_info.sriov_info.b_pf_asymetric_configuration = FALSE;
2472     }
2473 
2474 }
2475 
lm_get_shmem_mf_sriov_info(lm_device_t * pdev)2476 static void lm_get_shmem_mf_sriov_info(lm_device_t *pdev)
2477 {
2478     u32_t                     offset               = 0;
2479     u32_t                     val                  = 0;
2480     u8_t                      func                 = 0;
2481     const u8_t                abs_func             = ABS_FUNC_ID(pdev);
2482     u8_t                      abs_func_idx         = 0;
2483     u8_t                      sriov_enabled        = 0xff;
2484     u8_t                      sriov_disabled       = 0xff;
2485 
2486     ASSERT_STATIC((FIELD_SIZE(struct mf_cfg, func_mf_config) / FIELD_SIZE(struct mf_cfg, func_mf_config[0])) == E2_FUNC_MAX*2);
2487 
2488     if (CHIP_IS_E1x(pdev))
2489     {
2490         pdev->hw_info.sriov_info.shmem_num_vfs_in_pf = 0;
2491         pdev->hw_info.sriov_info.b_pf_asymetric_configuration = FALSE;
2492 
2493         return;
2494     }
2495 
2496     for (func = 0; func < E2_FUNC_MAX; func++)
2497     {
2498         abs_func_idx = PATH_ID(pdev) + func*2;
2499 
2500         offset = OFFSETOF(mf_cfg_t, func_mf_config[abs_func_idx].pf_allocation);
2501         LM_MFCFG_READ(pdev, offset,&val);
2502         val = (val & FUNC_MF_CFG_NUMBER_OF_VFS_MASK) >> FUNC_MF_CFG_NUMBER_OF_VFS_SHIFT;
2503 
2504         if (0 == val)
2505         {
2506             sriov_disabled = 1;
2507         }
2508         else
2509         {
2510             sriov_enabled = 1;
2511         }
2512 
2513         if (abs_func_idx == abs_func)
2514         {
2515             pdev->hw_info.sriov_info.shmem_num_vfs_in_pf = val;
2516         }
2517     }
2518 
2519 
2520     /* check if assymteric configuration...basically we initialize both params to 0xff, so the only way they can both be
2521      * the same is if one of the ports was enabled and one was disabled... */
2522     if (sriov_disabled == sriov_enabled)
2523     {
2524         pdev->hw_info.sriov_info.b_pf_asymetric_configuration = TRUE;
2525     }
2526     else
2527     {
2528         pdev->hw_info.sriov_info.b_pf_asymetric_configuration = FALSE;
2529     }
2530 
2531 }
2532 
2533 
lm_get_shmem_mac_info(lm_device_t * pdev)2534 static lm_status_t lm_get_shmem_mac_info(lm_device_t *pdev)
2535 {
2536     lm_status_t lm_status = LM_STATUS_SUCCESS;
2537 
2538     if (pdev->hw_info.mf_info.mf_mode == SINGLE_FUNCTION)
2539     {
2540         lm_status = lm_get_shmem_sf_mac_info(pdev);
2541     }
2542     else
2543     {
2544         lm_status = lm_get_shmem_mf_mac_info(pdev);
2545     }
2546 
2547     return lm_status;
2548 }
2549 
lm_get_shmem_sriov_info(lm_device_t * pdev)2550 static void lm_get_shmem_sriov_info(lm_device_t *pdev)
2551 {
2552     const u32_t bc_rev    = LM_GET_BC_REV_MAJOR(pdev);
2553 
2554     if (CHIP_IS_E1x(pdev) || (bc_rev < BC_REV_IE_SRIOV_SUPPORTED))
2555     {
2556         return;
2557     }
2558 
2559     if (pdev->hw_info.mf_info.mf_mode == SINGLE_FUNCTION)
2560     {
2561         lm_get_shmem_sf_sriov_info(pdev);
2562     }
2563     else
2564     {
2565         lm_get_shmem_mf_sriov_info(pdev);
2566     }
2567 }
2568 
lm_get_shmem_fw_flow_control(lm_device_t * pdev)2569 static void lm_get_shmem_fw_flow_control(lm_device_t *pdev)
2570 {
2571     u32_t func_ext_cfg = 0;
2572 
2573     // cq57766
2574     // if this static assert fails consider adding the new mode to the if
2575     // and read the l2_fw_flow_ctrl from the shmem in the new mode also
2576     ASSERT_STATIC(MAX_MF_MODE == 4);
2577     // l2_fw_flow_ctrl is read from the shmem in multi-function mode in E2 and above.
2578     // In all other cases this parameter is read from the registry.
2579     // We read this parameter from the registry in E1.5 multi-function since 57711 boot code does not have the struct func_ext_cfg
2580     if (((pdev->hw_info.mf_info.mf_mode == MULTI_FUNCTION_SI)   ||
2581          (pdev->hw_info.mf_info.mf_mode == MULTI_FUNCTION_AFEX)) &&
2582         (!CHIP_IS_E1x(pdev)))
2583     {
2584         LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_ext_config[ABS_FUNC_ID(pdev)].func_cfg), &func_ext_cfg);
2585         if (GET_FLAGS(func_ext_cfg, MACP_FUNC_CFG_PAUSE_ON_HOST_RING))
2586         {
2587             pdev->params.l2_fw_flow_ctrl = 1;
2588         }
2589         else
2590         {
2591             pdev->params.l2_fw_flow_ctrl = 0;
2592         }
2593     }
2594 }
2595 
2596 /**
2597  * @Description
2598  *     This function is responsible for reading all the data
2599  *     that the driver needs before loading from the shmem.
2600  *
2601  * @param pdev
2602  *
2603  * @return lm_status_t
2604  */
lm_get_shmem_info(lm_device_t * pdev)2605 lm_status_t lm_get_shmem_info(lm_device_t *pdev)
2606 {
2607     lm_status_t lm_status = LM_STATUS_SUCCESS;
2608     u32_t       val       = 0;
2609 
2610     lm_shmem_set_default(pdev);
2611 
2612     val = lm_get_shmem_base_addr(pdev);
2613     if (!val)
2614     {
2615         DbgMessage(pdev, WARNi, "NO MCP\n");
2616         return lm_get_shmem_info_no_mcp_bypass(pdev);
2617     }
2618 
2619     pdev->hw_info.mcp_detected = 1;
2620     pdev->hw_info.shmem_base   = val;
2621 
2622     pdev->hw_info.shmem_base2 = REG_RD(pdev, PATH_ID(pdev) ? MISC_REG_GENERIC_CR_1 : MISC_REG_GENERIC_CR_0);
2623     pdev->hw_info.mf_cfg_base = lm_get_shmem_mf_cfg_base(pdev);
2624 
2625     DbgMessage(pdev, WARNi, "MCP Up Detected. shmem_base=0x%x shmem_base2=0x%x mf_cfg_offset=0x%x\n",
2626                 pdev->hw_info.shmem_base, pdev->hw_info.shmem_base2, pdev->hw_info.mf_cfg_base);
2627 
2628     lm_status = lm_verify_validity_map( pdev );
2629     if(LM_STATUS_SUCCESS != lm_status )
2630     {
2631         DbgMessage(pdev, FATAL, "lm_get_shmem_info: Shmem signature not present.\n");
2632         pdev->hw_info.mcp_detected = 0;
2633         return LM_STATUS_SUCCESS;
2634      }
2635 
2636     /* bc rev */
2637     LM_SHMEM_READ(pdev,OFFSETOF(shmem_region_t,dev_info.bc_rev),&val);
2638     pdev->hw_info.bc_rev = val;
2639     DbgMessage(pdev, INFORMi, "bc_rev %d\n",val);
2640 
2641     lm_status = lm_get_shmem_shared_hw_config(pdev);
2642     if (lm_status != LM_STATUS_SUCCESS)
2643     {
2644         DbgMessage(pdev, WARNi, "lm_get_shmem_shared_hw_config returned lm_status=%d\n", lm_status);
2645         return lm_status;
2646     }
2647 
2648     lm_status = lm_get_shmem_port_hw_config(pdev);
2649     if (lm_status != LM_STATUS_SUCCESS)
2650     {
2651         DbgMessage(pdev, WARNi, "lm_get_shmem_port_hw_config returned lm_status=%d\n", lm_status);
2652         return lm_status;
2653     }
2654 
2655     /* Check License for toe/rdma/iscsi */
2656 #ifdef _LICENSE_H
2657     lm_status = lm_get_shmem_license_info(pdev);
2658     if (lm_status != LM_STATUS_SUCCESS)
2659     {
2660         DbgMessage(pdev, WARNi, "lm_get_shmem_license_info returned lm_status=%d\n", lm_status);
2661         return lm_status;
2662     }
2663 #endif
2664     /* get mf config parameters */
2665     if (IS_MF_MODE_CAPABLE(pdev) && (pdev->hw_info.mf_cfg_base != SHMEM_MF_CFG_ADDR_NONE))
2666     {
2667         lm_status = lm_get_shmem_mf_cfg_info(pdev);
2668         if (lm_status != LM_STATUS_SUCCESS)
2669         {
2670             DbgMessage(pdev, WARNi, "lm_get_shmem_mf_cfg_info returned lm_status=%d\n", lm_status);
2671             return lm_status;
2672         }
2673     }
2674     else if (FUNC_ID(pdev) != PORT_ID(pdev))
2675     {
2676         DbgMessage(pdev, WARNi, "Illegal to load func %d of port %d on non MF mode capable device\n");
2677         return LM_STATUS_FAILURE;
2678     }
2679 
2680     lm_get_shmem_sriov_info(pdev);
2681 
2682     lm_status = lm_get_shmem_mac_info(pdev);
2683 
2684     lm_get_shmem_fw_flow_control(pdev);
2685 
2686     return lm_status;
2687 }
2688 
init_link_params(lm_device_t * pdev)2689 void init_link_params(lm_device_t *pdev)
2690 {
2691     u32_t val              = 0;
2692     u32_t feat_val         = 0;
2693     const u8_t port     = PORT_ID(pdev);
2694 
2695     pdev->params.link.port        = port;
2696     pdev->params.link.lfa_base = 0;
2697     pdev->params.link.shmem_base = NO_MCP_WA_CLC_SHMEM;
2698     pdev->params.link.shmem2_base= NO_MCP_WA_CLC_SHMEM;
2699 
2700     if (pdev->hw_info.mcp_detected)
2701     {
2702         pdev->params.link.shmem_base = pdev->hw_info.shmem_base;
2703         pdev->params.link.shmem2_base= pdev->hw_info.shmem_base2;
2704 
2705         // Only if LFA is supported in MFW
2706         if (LM_SHMEM2_HAS(pdev,lfa_host_addr[port]))
2707         {
2708             LM_SHMEM2_READ(pdev, OFFSETOF(shmem2_region_t, lfa_host_addr[port]), &pdev->params.link.lfa_base);
2709         }
2710    }
2711 
2712     pdev->params.link.chip_id = pdev->hw_info.chip_id;
2713     pdev->params.link.cb      = pdev;
2714 
2715     ///TODO remove - the initialization in lm_mcp_cmd_init should be enough, but BC versions are still in flux.
2716     if(pdev->hw_info.mf_info.mf_mode == MULTI_FUNCTION_AFEX) //we can't use IS_MF_NIV_MODE because params.mf_mode is not initalized yet.
2717     {
2718         SET_FLAGS( pdev->params.link.feature_config_flags, ELINK_FEATURE_CONFIG_BC_SUPPORTS_AFEX );
2719     }
2720 
2721     if (CHIP_REV_IS_SLOW(pdev))
2722     {
2723         val = CHIP_BONDING(pdev);
2724         DbgMessage(pdev, WARN, "init_link_params: chip bond id is 0x%x\n",val);
2725 
2726         if (pdev->hw_info.chip_port_mode == LM_CHIP_PORT_MODE_4)
2727         {
2728             feat_val |= ELINK_FEATURE_CONFIG_EMUL_DISABLE_BMAC;
2729         }
2730         else if (val & 0x4)
2731         {
2732             // force to work with emac
2733             if (CHIP_IS_E3(pdev))
2734             {
2735                 pdev->params.link.req_line_speed[0] = ELINK_SPEED_1000;
2736                 feat_val |= ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC;
2737             }
2738             else
2739             {
2740                 feat_val |= ELINK_FEATURE_CONFIG_EMUL_DISABLE_BMAC;
2741             }
2742         }
2743         else if (val & 0x8)
2744         {
2745             if (CHIP_IS_E3(pdev))
2746             {
2747                 feat_val |= ELINK_FEATURE_CONFIG_EMUL_DISABLE_UMAC;
2748             }
2749             else
2750             {
2751                 feat_val |= ELINK_FEATURE_CONFIG_EMUL_DISABLE_EMAC;
2752             }
2753         }
2754         /* Disable EMAC for E3 and above */
2755         if (val & 2)
2756         {
2757             feat_val |= ELINK_FEATURE_CONFIG_EMUL_DISABLE_EMAC;
2758         }
2759 
2760         SET_FLAGS(pdev->params.link.feature_config_flags, feat_val);
2761     }
2762 }
2763 
2764 /** lm_init_cam_params
2765  *  set cam/mac parameters
2766  *
2767  *  cam mapping is dynamic, we only set sizes...
2768  *
2769  */
lm_init_cam_params(lm_device_t * pdev)2770 static void lm_init_cam_params(lm_device_t *pdev)
2771 {
2772     /* FIXME: remove once constants are in hsi file */
2773     #define LM_CAM_SIZE_EMUL                    (5)                                /*5 per vnic also in single function mode (real cam size on emulation is 20 per port) */
2774     #define LM_MC_TABLE_SIZE_EMUL               (1)
2775     #define LM_CAM_SIZE_EMUL_E2                 (40)
2776 
2777     u16_t mc_credit;
2778     u16_t uc_credit;
2779     u8_t b_is_asic = CHIP_REV_IS_ASIC(pdev);
2780     u8_t num_ports = 2;
2781     u8_t num_funcs;
2782 
2783     /* set CAM parameters according to EMUL/FPGA or ASIC + Chip*/
2784     mm_mem_zero(pdev->params.uc_table_size, sizeof(pdev->params.uc_table_size));
2785     mm_mem_zero(pdev->params.mc_table_size, sizeof(pdev->params.mc_table_size));
2786 
2787     if (CHIP_IS_E1(pdev))
2788     {
2789         pdev->params.cam_size = b_is_asic? MAX_MAC_CREDIT_E1 / num_ports : LM_CAM_SIZE_EMUL;
2790 
2791         mc_credit = b_is_asic? LM_MC_NDIS_TABLE_SIZE : LM_MC_TABLE_SIZE_EMUL;
2792         uc_credit = pdev->params.cam_size - mc_credit; /* E1 multicast is in CAM */
2793 
2794     /* init unicast table entires */
2795     pdev->params.uc_table_size[LM_CLI_IDX_ISCSI]    = 1;
2796         pdev->params.uc_table_size[LM_CLI_IDX_NDIS]  = uc_credit - 1; /* - one for iscsi... */
2797 
2798     /* init multicast table entires */
2799         pdev->params.mc_table_size[LM_CLI_IDX_NDIS] = mc_credit;
2800 
2801         DbgMessage(pdev, INFORMi, "uc_table_size[ndis]=%d, uc_table_size[ndis]=%d, mc_table_size[ndis]=%d\n",
2802                    pdev->params.uc_table_size[LM_CLI_IDX_NDIS], pdev->params.uc_table_size[LM_CLI_IDX_ISCSI],
2803                    pdev->params.mc_table_size[LM_CLI_IDX_NDIS]);
2804 
2805     }
2806     else if (CHIP_IS_E1H(pdev))
2807     {
2808         pdev->params.cam_size = b_is_asic? MAX_MAC_CREDIT_E1H / num_ports: LM_CAM_SIZE_EMUL;
2809         pdev->params.cam_size = pdev->params.cam_size / pdev->params.vnics_per_port;
2810         uc_credit = pdev->params.cam_size;
2811 
2812         /* init unicast table entires */
2813         pdev->params.uc_table_size[LM_CLI_IDX_ISCSI] = 1;
2814         pdev->params.uc_table_size[LM_CLI_IDX_NDIS]  = uc_credit - 1; /* - one for iscsi... */
2815 
2816         /* init multicast table entires */
2817         pdev->params.mc_table_size[LM_CLI_IDX_NDIS] = LM_MC_NDIS_TABLE_SIZE;
2818 
2819         DbgMessage(pdev, INFORMi, "uc_table_size[ndis]=%d, uc_table_size[ndis]=%d, mc_table_size[ndis]=%d\n",
2820                    pdev->params.uc_table_size[LM_CLI_IDX_NDIS], pdev->params.uc_table_size[LM_CLI_IDX_ISCSI],
2821                    pdev->params.mc_table_size[LM_CLI_IDX_NDIS]);
2822     }
2823     else if (CHIP_IS_E2E3(pdev))
2824     {
2825         num_ports = (CHIP_PORT_MODE(pdev) == LM_CHIP_PORT_MODE_4)? 2 : 1;
2826     num_funcs = VNICS_PER_PATH(pdev);
2827     if (num_funcs > 1)
2828     {
2829         pdev->params.cam_size = b_is_asic? ((MAX_MAC_CREDIT_E2 - GET_NUM_VFS_PER_PATH(pdev))/ num_funcs + GET_NUM_VFS_PER_PF(pdev)): LM_CAM_SIZE_EMUL_E2;
2830     }
2831     else
2832     {
2833         pdev->params.cam_size = b_is_asic? MAX_MAC_CREDIT_E2 : LM_CAM_SIZE_EMUL_E2;
2834     }
2835         uc_credit = pdev->params.cam_size;
2836 
2837         /* init unicast table entires */
2838         pdev->params.uc_table_size[LM_CLI_IDX_ISCSI] = 1;
2839         pdev->params.uc_table_size[LM_CLI_IDX_FCOE]  = 1;
2840         pdev->params.uc_table_size[LM_CLI_IDX_NDIS]  = uc_credit - 2; /* - the two above... */
2841 
2842         /* init multicast table entires */
2843         pdev->params.mc_table_size[LM_CLI_IDX_NDIS] = LM_MC_NDIS_TABLE_SIZE;
2844         pdev->params.mc_table_size[LM_CLI_IDX_FCOE] = LM_MC_FCOE_TABLE_SIZE;
2845 
2846         DbgMessage(pdev, INFORMi, "uc_table_size[ndis]=%d, uc_table_size[ndis]=%d, uc_table_size[fcoe]=%d, mc_table_size[ndis]=%d, mc_table_size[fcoe]=%d\n",
2847                     pdev->params.uc_table_size[LM_CLI_IDX_NDIS], pdev->params.uc_table_size[LM_CLI_IDX_ISCSI],
2848                     pdev->params.uc_table_size[LM_CLI_IDX_FCOE],
2849                     pdev->params.mc_table_size[LM_CLI_IDX_NDIS], pdev->params.mc_table_size[LM_CLI_IDX_FCOE]);
2850     }
2851     else
2852     {
2853         DbgBreakIfAll("New Chip?? initialize cam params!\n");
2854     }
2855 
2856     /* override CAM parameters for chips later than E1 */
2857     if (IS_PFDEV(pdev))
2858     {
2859         pdev->params.base_offset_in_cam_table = ((num_ports == 2)? FUNC_ID(pdev) : VNIC_ID(pdev)) * LM_CAM_SIZE(pdev);
2860     }
2861     else if (IS_CHANNEL_VFDEV(pdev))
2862     {
2863         pdev->params.base_offset_in_cam_table = 0;
2864         pdev->params.mc_table_size[LM_CLI_IDX_NDIS] = 0; /* Will be filled later on acquire response (HW_CHANNEL)*/
2865     }
2866 }
2867 
2868 /*
2869  * \brief Initialize pdev->params members
2870  *
2871  * This function initializes the various pdev->params members, depending
2872  * on chip technology/implementation: fpga, emul or asic (default).
2873  *
2874  * The function may also be used to validate these parameters.
2875  *
2876  * \param[in,out]   pdev
2877  * \param[in]       validate        flag to indicate desired operation.
2878  *
2879  * \return success/failure indication
2880  */
2881 
lm_init_params(lm_device_t * pdev,u8_t validate)2882 static lm_status_t lm_init_params(lm_device_t *pdev, u8_t validate)
2883 {
2884     typedef struct _param_entry_t
2885     {
2886         /* Ideally, we want to save the address of the parameter here.
2887         * However, some compiler will not allow us to dynamically
2888         * initialize the pointer to a parameter in the table below.
2889         * As an alternative, we will save the offset to the parameter
2890         * from pdev device structure. */
2891         u32_t offset;
2892         /* Parameter default value. */
2893         u32_t asic_default;
2894         u32_t fpga_default;
2895         u32_t emulation_default;
2896         /* Limit checking is diabled if min and max are zeros. */
2897         u32_t min;
2898         u32_t max;
2899     } param_entry_t;
2900     #define _OFFSET(_name)          (OFFSETOF(lm_device_t, params._name))
2901     #define PARAM_VAL(_pdev, _entry) \
2902         (*((u32_t *) ((u8_t *) (_pdev) + (_entry)->offset)))
2903     #define SET_PARAM_VAL(_pdev, _entry, _val) \
2904         *((u32_t *) ((u8_t *) (_pdev) + (_entry)->offset)) = (_val)
2905     static param_entry_t param_list[] =
2906     {
2907         /*                                 asic     fpga     emul
2908         offset                          default  default  default min     max */
2909         { _OFFSET(mtu[LM_CLI_IDX_NDIS]),  9216,    9216,    9216,   1500,   9216 },
2910         { _OFFSET(mtu[LM_CLI_IDX_ISCSI]),  9216,    9216,    9216,   1500,   9216 },
2911         { _OFFSET(mtu[LM_CLI_IDX_FCOE]),  9216,    9216,    9216,   1500,   9216 },
2912 //        { _OFFSET(mtu[LM_CLI_IDX_RDMA]),  LM_MTU_INVALID_VALUE,    LM_MTU_INVALID_VALUE,    LM_MTU_INVALID_VALUE,   LM_MTU_INVALID_VALUE,   LM_MTU_INVALID_VALUE },
2913         { _OFFSET(mtu[LM_CLI_IDX_OOO]),  9216,    9216,    9216,   1500,   9216 },
2914         { _OFFSET(mtu[LM_CLI_IDX_FWD]),  9216,    9216,    9216,   1500,   9216 },
2915         { _OFFSET(mtu_max),  9216,    9216,    9216,   1500,   9216 },
2916         { _OFFSET(rcv_buffer_offset),      0,       0,       0,      0,   9000 },
2917         { _OFFSET(l2_rx_desc_cnt[LM_CLI_IDX_NDIS]),      200,     200,     200,    0,      32767 },
2918         { _OFFSET(l2_rx_desc_cnt[LM_CLI_IDX_FCOE]),      200,     200,     200,    0,      32767 },
2919         { _OFFSET(l2_rx_desc_cnt[LM_CLI_IDX_OOO]),       500,     500,     500,    0,      32767 },
2920         /* The maximum page count is chosen to prevent us from having
2921         * more than 32767 pending entries at any one time. */
2922         { _OFFSET(l2_tx_bd_page_cnt[LM_CLI_IDX_NDIS]),   2,       2,       2,      1,      127 },
2923         { _OFFSET(l2_tx_bd_page_cnt[LM_CLI_IDX_FCOE]),   2,       2,       2,      1,      127 },
2924         { _OFFSET(l2_tx_coal_buf_cnt[LM_CLI_IDX_NDIS]),  0,       0,       0,      0,      20 },
2925         { _OFFSET(l2_tx_coal_buf_cnt[LM_CLI_IDX_FCOE]),  0,       0,       0,      0,      20 },
2926         { _OFFSET(l2_tx_bd_page_cnt[LM_CLI_IDX_FWD]) ,   2,       2,       2,      1,      127 },
2927         /* NirV: still not supported in ediag, being set in the windows mm */
2928 //        { _OFFSET(l2_rx_desc_cnt[LM_CLI_IDX_ISCSI]),      200,     200,     200,    0,      32767 },
2929 //
2930 //        /* The maximum page count is chosen to prevent us from having
2931 //        * more than 32767 pending entries at any one time. */
2932 //        { _OFFSET(l2_tx_bd_page_cnt[LM_CLI_IDX_ISCSI]),   2,       2,       2,      1,      127 },
2933 //        { _OFFSET(l2_tx_coal_buf_cnt[LM_CLI_IDX_ISCSI]),  0,       0,       0,      0,      20 },
2934 //        { _OFFSET(l2_rx_bd_page_cnt[LM_CLI_IDX_ISCSI]),   1,       1,       1,      1,      127 },
2935         { _OFFSET(test_mode),              0,       0,       0,      0,      0 },
2936         { _OFFSET(ofld_cap),               0,       0,       0,      0,      0 },
2937         { _OFFSET(wol_cap),                0,       0,       0,      0,      0 },
2938         { _OFFSET(i2c_interval_sec),       0,       0,       0,      0,      1000 },
2939         { _OFFSET(flow_ctrl_cap),          0,       0,       0,      0,      0x80000000 },
2940         { _OFFSET(eee_policy),             LM_EEE_CONTROL_NVRAM, LM_EEE_CONTROL_NVRAM, LM_EEE_CONTROL_NVRAM, LM_EEE_CONTROL_HIGH, LM_EEE_CONTROL_NVRAM }, // registry values are 0-5 for this
2941         { _OFFSET(req_medium),             0xff00,  0x00ff,  0x00ff, 0,   0xfffff },
2942         { _OFFSET(interrupt_mode),         LM_INT_MODE_INTA, LM_INT_MODE_INTA, LM_INT_MODE_INTA, LM_INT_MODE_INTA, LM_INT_MODE_MIMD},
2943         { _OFFSET(igu_access_mode),        INTR_BLK_ACCESS_IGUMEM, INTR_BLK_ACCESS_IGUMEM, INTR_BLK_ACCESS_IGUMEM, INTR_BLK_ACCESS_GRC, INTR_BLK_ACCESS_IGUMEM},
2944         { _OFFSET(sw_config),              4,       4,       4,      0,      4},
2945         { _OFFSET(selective_autoneg),      0,       0,       0,      0,      0 },
2946         { _OFFSET(autogreeen),             LM_AUTOGREEEN_NVRAM,       LM_AUTOGREEEN_NVRAM,       LM_AUTOGREEEN_NVRAM,      LM_AUTOGREEEN_DISABLED,      LM_AUTOGREEEN_NVRAM },
2947         { _OFFSET(wire_speed),             1,       0,       0,      0,      0 },
2948         { _OFFSET(phy_int_mode),           2,       2,       2,      0,      0 },
2949         { _OFFSET(link_chng_mode),         2,       2,       2,      0,      0 },
2950         // TODO add correct values here
2951         { _OFFSET(max_func_connections),   1024,    1024,    1024,   0,      500000},
2952 #ifdef VF_INVOLVED
2953         { _OFFSET(max_func_toe_cons),      310,     310,     310,    0,      500000},
2954 #else
2955         { _OFFSET(max_func_toe_cons),      750,     750,     750,    0,      500000},
2956 #endif
2957         { _OFFSET(max_func_rdma_cons),     10,       10,      10,    0,      500000},
2958         { _OFFSET(max_func_iscsi_cons),    128,     128,     128,    0,      500000},
2959         { _OFFSET(max_func_fcoe_cons),     64,      64,      20,     0,      500000},
2960         { _OFFSET(context_line_size),      LM_CONTEXT_SIZE,    LM_CONTEXT_SIZE,    LM_CONTEXT_SIZE,   0,      LM_CONTEXT_SIZE },
2961         { _OFFSET(context_waste_size),     0,       0,       0,      0,      1024 },
2962         { _OFFSET(num_context_in_page),    4,       4,       4,      0,       128},
2963         { _OFFSET(client_page_size),       0x1000, 0x1000, 0x1000,0x1000, 0x20000 },
2964         { _OFFSET(elt_page_size),          0x1000, 0x1000, 0x1000,0x1000, 0x20000 },
2965         { _OFFSET(ilt_client_page_size),   0x1000, 0x1000, 0x1000,0x1000, 0x20000 },
2966         { _OFFSET(cfc_last_lcid),          0xff,   0xff,   0xff,    0x1,     0xff },
2967         { _OFFSET(override_rss_chain_cnt), 0,      0,      0,       0,       16 },
2968         // network type and max cwnd
2969         { _OFFSET(network_type),   LM_NETOWRK_TYPE_WAN, LM_NETOWRK_TYPE_WAN, LM_NETOWRK_TYPE_WAN,LM_NETOWRK_TYPE_LAN, LM_NETOWRK_TYPE_WAN },
2970         { _OFFSET(max_cwnd_wan),   12500000, 12500000, 12500000,12500000, 12500000 },
2971         { _OFFSET(max_cwnd_lan),   1250000 , 1250000,  1250000, 1250000,  1250000 },
2972         // cid allocation mode
2973         { _OFFSET(cid_allocation_mode),     LM_CID_ALLOC_DELAY , LM_CID_ALLOC_DELAY, LM_CID_ALLOC_DELAY,LM_CID_ALLOC_DELAY, LM_CID_ALLOC_NUM_MODES},
2974         // interrupt coalesing configuration
2975         { _OFFSET(int_coalesing_mode),      LM_INT_COAL_PERIODIC_SYNC, LM_INT_COAL_NONE, LM_INT_COAL_NONE, 1, LM_INT_COAL_NUM_MODES },
2976         { _OFFSET(int_per_sec_rx[0]),          5000,    5000,    5000,  1,      200000 },
2977         { _OFFSET(int_per_sec_rx[1]),          5000,    5000,    5000,  1,      200000 },
2978         { _OFFSET(int_per_sec_rx[2]),          5000,    5000,    5000,  1,      200000 },
2979         { _OFFSET(int_per_sec_rx[3]),          5000,    5000,    5000,  1,      200000 },
2980         { _OFFSET(int_per_sec_tx[0]),          7500,    7500,    7500,  1,      200000 },
2981         { _OFFSET(int_per_sec_tx[1]),          3800,    3800,    3800,  1,      200000 },
2982         { _OFFSET(int_per_sec_tx[2]),          3800,    3800,    3800,  1,      200000 },
2983         { _OFFSET(int_per_sec_tx[3]),          3800,    3800,    3800,  1,      200000 },
2984         // VF interrupt coalesing configuration
2985         { _OFFSET(vf_int_per_sec_rx[LM_VF_INT_LOW_IDX]),    5000,    5000,    5000,  1,      200000 },
2986         { _OFFSET(vf_int_per_sec_rx[LM_VF_INT_MEDIUM_IDX]), 10000,    5000,    5000,  1,      200000 },
2987         { _OFFSET(vf_int_per_sec_rx[LM_VF_INT_HIGH_IDX]),   20000,    5000,    5000,  1,      200000 },
2988         { _OFFSET(vf_int_per_sec_tx[LM_VF_INT_LOW_IDX]),    3800,    3800,    3800,  1,      200000 },
2989         { _OFFSET(vf_int_per_sec_tx[LM_VF_INT_MEDIUM_IDX]), 8000,    3800,    3800,  1,      200000 },
2990         { _OFFSET(vf_int_per_sec_tx[LM_VF_INT_HIGH_IDX]),   16000,    3800,    3800,  1,      200000 },
2991 
2992         { _OFFSET(enable_dynamic_hc[0]),    1,       1,       1,     0,      1 },
2993         { _OFFSET(enable_dynamic_hc[1]),    1,       1,       1,     0,      1 },
2994         { _OFFSET(enable_dynamic_hc[2]),    1,       1,       1,     0,      1 },
2995         { _OFFSET(enable_dynamic_hc[3]),    0,       0,       0,     0,      1 },
2996         { _OFFSET(hc_timeout0[SM_RX_ID][0]),       12,      12,      12,    1,      0xff },   /* (20K int/sec assuming no more btr) */
2997         { _OFFSET(hc_timeout1[SM_RX_ID][0]),       48,      48,      48,    1,      0xff },   /* (5K int/sec assuming no more btr) */
2998         { _OFFSET(hc_timeout2[SM_RX_ID][0]),       48,      48,      48,    1,      0xff },   /* (5K int/sec assuming no more btr) */
2999         { _OFFSET(hc_timeout3[SM_RX_ID][0]),       48,      48,      48,    1,      0xff },   /* (5K int/sec assuming no more btr) */
3000         { _OFFSET(hc_timeout0[SM_RX_ID][1]),       6,       6,       6,     1,      0xff },   /* (40K int/sec assuming no more btr) */
3001         { _OFFSET(hc_timeout1[SM_RX_ID][1]),       48,      48,      48,    1,      0xff },   /* (5K int/sec assuming no more btr) */
3002         { _OFFSET(hc_timeout2[SM_RX_ID][1]),       120,    120,     120,    1,      0xff },   /* (2K int/sec assuming no more btr) */
3003         { _OFFSET(hc_timeout3[SM_RX_ID][1]),       240,    240,     240,    1,      0xff },   /* (1K int/sec assuming no more btr) */
3004         { _OFFSET(hc_timeout0[SM_RX_ID][2]),       6,       6,       6,     1,      0xff },   /* (40K int/sec assuming no more btr) */
3005         { _OFFSET(hc_timeout1[SM_RX_ID][2]),       48,      48,      48,    1,      0xff },   /* (5K int/sec assuming no more btr) */
3006         { _OFFSET(hc_timeout2[SM_RX_ID][2]),       120,    120,     120,    1,      0xff },   /* (2K int/sec assuming no more btr) */
3007         { _OFFSET(hc_timeout3[SM_RX_ID][2]),       240,    240,     240,    1,      0xff },   /* (1K int/sec assuming no more btr) */
3008         { _OFFSET(hc_timeout0[SM_RX_ID][3]),       6,       6,       6,     1,      0xff },   /* (40K int/sec assuming no more btr) */
3009         { _OFFSET(hc_timeout1[SM_RX_ID][3]),       48,      48,      48,    1,      0xff },   /* (5K int/sec assuming no more btr) */
3010         { _OFFSET(hc_timeout2[SM_RX_ID][3]),       120,    120,     120,    1,      0xff },   /* (2K int/sec assuming no more btr) */
3011         { _OFFSET(hc_timeout3[SM_RX_ID][3]),       240,    240,     240,    1,      0xff },   /* (1K int/sec assuming no more btr) */
3012 
3013         { _OFFSET(hc_timeout0[SM_TX_ID][0]),       12,      12,      12,    1,      0xff },   /* (20K int/sec assuming no more btr) */
3014         { _OFFSET(hc_timeout1[SM_TX_ID][0]),       48,      48,      48,    1,      0xff },   /* (5K int/sec assuming no more btr) */
3015         { _OFFSET(hc_timeout2[SM_TX_ID][0]),       48,      48,      48,    1,      0xff },   /* (5K int/sec assuming no more btr) */
3016         { _OFFSET(hc_timeout3[SM_TX_ID][0]),       48,      48,      48,    1,      0xff },   /* (5K int/sec assuming no more btr) */
3017         { _OFFSET(hc_timeout0[SM_TX_ID][1]),       6,       6,       6,     1,      0xff },   /* (40K int/sec assuming no more btr) */
3018         { _OFFSET(hc_timeout1[SM_TX_ID][1]),       48,      48,      48,    1,      0xff },   /* (5K int/sec assuming no more btr) */
3019         { _OFFSET(hc_timeout2[SM_TX_ID][1]),       120,    120,     120,    1,      0xff },   /* (2K int/sec assuming no more btr) */
3020         { _OFFSET(hc_timeout3[SM_TX_ID][1]),       240,    240,     240,    1,      0xff },   /* (1K int/sec assuming no more btr) */
3021         { _OFFSET(hc_timeout0[SM_TX_ID][2]),        6,       6,       6,    1,      0xff },   /* (40K int/sec assuming no more btr) */
3022         { _OFFSET(hc_timeout1[SM_TX_ID][2]),       12,      12,      12,    1,      0xff },   /* (20K int/sec assuming no more btr) */
3023         { _OFFSET(hc_timeout2[SM_TX_ID][2]),       48,      48,      48,    1,      0xff },   /* (5K int/sec assuming no more btr) */
3024         { _OFFSET(hc_timeout3[SM_TX_ID][2]),       64,      64,      64,    1,      0xff },   /* (3.75K int/sec assuming no more btr) */
3025         { _OFFSET(hc_timeout0[SM_TX_ID][3]),       6,       6,       6,     1,      0xff },   /* (40K int/sec assuming no more btr) */
3026         { _OFFSET(hc_timeout1[SM_TX_ID][3]),       48,      48,      48,    1,      0xff },   /* (5K int/sec assuming no more btr) */
3027         { _OFFSET(hc_timeout2[SM_TX_ID][3]),       120,    120,     120,    1,      0xff },   /* (2K int/sec assuming no more btr) */
3028         { _OFFSET(hc_timeout3[SM_TX_ID][3]),       240,    240,     240,    1,      0xff },   /* (1K int/sec assuming no more btr) */
3029 
3030         { _OFFSET(hc_threshold0[SM_RX_ID]),        0x2000,  0x2000,  0x2000,1,     0xffffffff },
3031         { _OFFSET(hc_threshold1[SM_RX_ID]),        0x10000, 0x10000, 0x10000,1,     0xffffffff },
3032         { _OFFSET(hc_threshold2[SM_RX_ID]),        0x50000, 0x50000, 0x50000,1,     0xffffffff },
3033 
3034         { _OFFSET(hc_threshold0[SM_TX_ID]),        0x2000,  0x2000,  0x2000,1,     0xffffffff },
3035         { _OFFSET(hc_threshold1[SM_TX_ID]),        0x10000, 0x10000, 0x10000,1,     0xffffffff },
3036         { _OFFSET(hc_threshold2[SM_TX_ID]),        0x20000, 0x20000, 0x20000,1,     0xffffffff },
3037 
3038         { _OFFSET(l2_dynamic_hc_min_bytes_per_packet),        0,      0,        0,        0,     0xffff },
3039 //        { _OFFSET(l4_hc_scaling_factor),     12,      12,        12,      0,    16 },
3040         { _OFFSET(l4_hc_ustorm_thresh),     12,     12,       12,     12,     0xffffffff },  /* 128K */
3041         // l4 params
3042         { _OFFSET(l4_scq_page_cnt),         2,       2,       2,     2,      127 }, /* 321 BDs are reserved to FW threshold :-( */
3043         { _OFFSET(l4_rcq_page_cnt),         3,       3,       3,     3,      127 }, /* 398 BDs are reserved to FW threshold :-(  CQ_XOFF_TH = ((65*6) +  8) = ((maximum pending incoming msgs) * (maximum completions) + (maximum ramrods)) */
3044         { _OFFSET(l4_grq_page_cnt),         2,       2,       2,     2,      127 }, /* 65  BDs are reserved to FW threshold :-( */
3045         { _OFFSET(l4_tx_chain_page_cnt),    2,       2,       2,     2,      127 },
3046         { _OFFSET(l4_rx_chain_page_cnt),    2,       2,       2,     2,      127 },
3047         { _OFFSET(l4_gen_buf_size),         LM_PAGE_SIZE,LM_PAGE_SIZE,LM_PAGE_SIZE,LM_PAGE_SIZE,16*LM_PAGE_SIZE },
3048         { _OFFSET(l4_history_cqe_cnt),      20,      20,      20,    1,      20   },
3049         { _OFFSET(l4_ignore_grq_push_enabled), 0,       0,       0,     0,      1   },
3050         { _OFFSET(l4cli_flags),             0,       0,       0,     0,      1 },
3051         { _OFFSET(l4cli_ticks_per_second),  1000,    1000,    1000,  500,    10000 },
3052         { _OFFSET(l4cli_ack_frequency),     2,       2,       2,     1,      255 }, /* default 2 segments */
3053         { _OFFSET(l4cli_delayed_ack_ticks), 200,     200,     200,   1,      255 }, /* default 200ms */
3054         { _OFFSET(l4cli_max_retx),          6,       6,       6,     1,      255 },
3055         { _OFFSET(l4cli_doubt_reachability_retx),3,  3,       3,     1,      255 },
3056         { _OFFSET(l4cli_sws_prevention_ticks), 1000, 1000,    1000,  200,    0xffffffff }, /* default 1s */
3057         { _OFFSET(l4cli_dup_ack_threshold), 3,       3,       3,     1,      255 },
3058         { _OFFSET(l4cli_push_ticks),        100,     100,     100,   1,      0xffffffff }, /* default 100ms */
3059         { _OFFSET(l4cli_nce_stale_ticks),   0xffffff,0xffffff,0xffffff, 1,   0xffffffff },
3060         { _OFFSET(l4cli_starting_ip_id),    0,       0,       0,     0,      0xffff },
3061         { _OFFSET(keep_vlan_tag),           1 ,      1,       1,     0,      1 },
3062         //congestion managment parameters
3063         { _OFFSET(cmng_enable),             0,       0,       0,     0,      1},
3064         { _OFFSET(cmng_rate_shaping_enable),1,       1,       1,     0,      1},
3065         { _OFFSET(cmng_fairness_enable),    1,       1,       1,     0,      1},
3066         // safc
3067         { _OFFSET(cmng_safc_rate_thresh),   3,       3,       3,     0,      10},
3068         { _OFFSET(cmng_activate_safc),      0,       0,       0,     0,      1},
3069         // fairness
3070         { _OFFSET(cmng_fair_port0_rate),    10,      10,      10,    1,      10},
3071         { _OFFSET(cmng_eth_weight),         8,       8,       8,     0,      10},
3072         { _OFFSET(cmng_toe_weight),         8,       8,       8,     0,      10},
3073         { _OFFSET(cmng_rdma_weight),        8,       8,       8,     0,      10},
3074         { _OFFSET(cmng_iscsi_weight),       8,       8,       8,     0,      10},
3075         // rate shaping
3076         { _OFFSET(cmng_eth_rate),           10,      10,      10,    0,      10},
3077         { _OFFSET(cmng_toe_rate),           10,      10,      10,    0,      10},
3078         { _OFFSET(cmng_rdma_rate),          2,       2,       2,     0,      10},
3079         { _OFFSET(cmng_iscsi_rate),         4,       2,       2,     0,      10},
3080         // Demo will be removed later
3081         { _OFFSET(cmng_toe_con_number),     20,      20,      20,    0,      1024},
3082         { _OFFSET(cmng_rdma_con_number),    2,       2,       2,     0,      1024},
3083         { _OFFSET(cmng_iscsi_con_number),   40,      40,      40,    0,      1024},
3084         // iscsi
3085         { _OFFSET(l5sc_max_pending_tasks),      64,          64,      64,    64,     2048},
3086         // fcoe
3087         { _OFFSET(max_fcoe_task),           64,      64,      64,    0,     4096},
3088 #if 0
3089         { _OFFSET(disable_patent_using),        1,       1,       1,     0,      1},
3090 #else
3091         { _OFFSET(disable_patent_using),        0,       0,       0,     0,      1},
3092 #endif
3093         { _OFFSET(l4_grq_filling_threshold_divider),    64,       64,       64,     2,      2048},
3094         { _OFFSET(l4_free_cid_delay_time),  2000,   10000,      10000,  0,  10000},
3095         { _OFFSET(preemphasis_enable),      0,       0,       0,     0,      1},
3096         { _OFFSET(preemphasis_rx_0),        0,       0,       0,     0,      0xffff},
3097         { _OFFSET(preemphasis_rx_1),        0,       0,       0,     0,      0xffff},
3098         { _OFFSET(preemphasis_rx_2),        0,       0,       0,     0,      0xffff},
3099         { _OFFSET(preemphasis_rx_3),        0,       0,       0,     0,      0xffff},
3100         { _OFFSET(preemphasis_tx_0),        0,       0,       0,     0,      0xffff},
3101         { _OFFSET(preemphasis_tx_1),        0,       0,       0,     0,      0xffff},
3102         { _OFFSET(preemphasis_tx_2),        0,       0,       0,     0,      0xffff},
3103         { _OFFSET(preemphasis_tx_3),        0,       0,       0,     0,      0xffff},
3104         { _OFFSET(disable_pcie_nfr),        0,       0,       0,     0,      1},
3105         { _OFFSET(debug_cap_flags),  0xffffffff,       0xffffffff,       0xffffffff,     0,      0xffffffff},
3106         { _OFFSET(try_not_align_page_multiplied_memory),     1,       1,       1,     0,      1},
3107         { _OFFSET(l4_limit_isles),          0,       0,       0,     0,      1},
3108         { _OFFSET(l4_max_rcv_wnd_size),     0x100000,0x100000,0x100000, 0,      0x1000000},
3109         { _OFFSET(ndsb_type),               1,       1,       1,     0,      2},
3110         { _OFFSET(l4_dominance_threshold),  10,      10,      10,     0,      0xFF},
3111         { _OFFSET(l4_max_dominance_value),  20,     20,      20,     0,      0xFF},
3112         { _OFFSET(l4_data_integrity),       0x0,     0x0,     0x0,   0x0,      0x3},
3113         { _OFFSET(l4_start_port),           5001,  5001,      5001,  0,      0xFFFFFFFF},
3114         { _OFFSET(l4_num_of_ports),         50,      50,      50,     0,      0xFFFF},
3115         { _OFFSET(l4_skip_start_bytes),     4,       4,       4,     0,      0xFFFFFFFF},
3116         { _OFFSET(phy_priority_mode),       PHY_PRIORITY_MODE_HW_DEF, PHY_PRIORITY_MODE_HW_DEF, PHY_PRIORITY_MODE_HW_DEF, PHY_PRIORITY_MODE_HW_DEF, PHY_PRIORITY_MODE_HW_PIN},
3117         { _OFFSET(grc_timeout_max_ignore),  0,       0,       0,     0,      0xFFFFFFFF},
3118         { _OFFSET(enable_error_recovery),   0,       0,       0,     0,      1},
3119         { _OFFSET(validate_sq_complete),    0,       0,       0,     0,      1},
3120         { _OFFSET(npar_vm_switching_enable),0,       0,       0,     0,      1},
3121         { _OFFSET(flow_control_reporting_mode),LM_FLOW_CONTROL_REPORTING_MODE_DISABLED,LM_FLOW_CONTROL_REPORTING_MODE_DISABLED,LM_FLOW_CONTROL_REPORTING_MODE_DISABLED,LM_FLOW_CONTROL_REPORTING_MODE_DISABLED,LM_FLOW_CONTROL_REPORTING_MODE_ENABLED},
3122         { _OFFSET(tpa_desc_cnt_per_chain),  0,       0,       0,     0,      0x10000},
3123         { _OFFSET(sriov_inc_mac),           0,       0,       0,     0,      64},
3124         { _OFFSET(e3_cos_modes),            0,       0,       0,     0,      1},
3125         { _OFFSET(e3_network_cos_mode),     0,       0,       0,     0,      1},
3126         { _OFFSET(fw_valid_mask),           0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0, 0xFFFFFFFF},
3127         { _OFFSET(record_sp),               0x0,     0x0,     0x0,   0,      0xf},
3128         { 0,                                0,       0,       0,     0,      0}
3129     }; // param_list
3130 
3131     param_entry_t  *param               = NULL;
3132     size_t          csize               = 0;
3133     u32_t           flow_control        = 0;
3134     u8_t            i                   = 0;
3135     u8_t            port_base_aux_qzone = 0;
3136     u8_t            base_fw_qzone_id = 0;
3137     DbgMessage(pdev, INFORMi , "### lm_init_param\n");
3138     if (!validate)
3139     {
3140         /* Initialize the default parameters. */
3141         param = param_list;
3142         while(param->offset)
3143         {
3144             if(CHIP_REV_IS_FPGA(pdev))
3145             {
3146                 SET_PARAM_VAL(pdev, param, param->fpga_default);
3147             }
3148             else if(CHIP_REV_IS_EMUL(pdev))
3149             {
3150                 SET_PARAM_VAL(pdev, param, param->emulation_default);
3151             }
3152             else
3153             {
3154                 SET_PARAM_VAL(pdev, param, param->asic_default);
3155             }
3156             param++;
3157         }
3158         pdev->params.rss_caps = (LM_RSS_CAP_IPV4 | LM_RSS_CAP_IPV6);
3159         pdev->params.rss_chain_cnt = 1;
3160         pdev->params.tss_chain_cnt = 1;
3161         if (IS_PFDEV(pdev))
3162         {
3163             pdev->params.sb_cnt = MAX_RSS_CHAINS / pdev->params.vnics_per_port;
3164             /* base non-default status block idx - 0 in E1. 0, 4, 8 or 12 in E1H */
3165             if (CHIP_IS_E1x(pdev))
3166             {
3167                 pdev->params.max_pf_sb_cnt = pdev->params.fw_sb_cnt = HC_SB_MAX_SB_E1X / 2 / pdev->params.vnics_per_port;
3168                 pdev->params.base_fw_ndsb = FUNC_ID(pdev) * pdev->params.fw_sb_cnt;
3169                 if (CHIP_IS_E1(pdev)) {
3170                     pdev->params.fw_client_cnt = pdev->params.max_pf_fw_client_cnt = ETH_MAX_RX_CLIENTS_E1;
3171                 } else {
3172                     pdev->params.fw_client_cnt = pdev->params.max_pf_fw_client_cnt = ETH_MAX_RX_CLIENTS_E1H / pdev->params.vnics_per_port;
3173                 }
3174                 pdev->params.base_fw_client_id = VNIC_ID(pdev) * pdev->params.fw_client_cnt;
3175             }
3176             else
3177             {
3178 #ifdef _VBD_
3179 //      pdev->params.sb_cnt = min(LM_IGU_SB_CNT(pdev), MAX_RSS_CHAINS);
3180         pdev->params.sb_cnt = LM_IGU_SB_CNT(pdev);
3181 #endif
3182                 if (pdev->params.sb_cnt > LM_IGU_SB_CNT(pdev)) {
3183                     pdev->params.sb_cnt = LM_IGU_SB_CNT(pdev);
3184                 }
3185 // Asymmetric resource division
3186 #ifndef LM_NUM_DSBS
3187 #define LM_NUM_DSBS 1
3188 #endif
3189                 if (CHIP_PORT_MODE(pdev) == LM_CHIP_PORT_MODE_4)
3190                 {
3191                     pdev->params.base_fw_ndsb = IGU_BASE_NDSB(pdev) - (FUNC_ID(pdev) + 1)* LM_NUM_DSBS;
3192                     pdev->params.fw_aux_qzone_cnt = (ETH_MAX_RX_CLIENTS_E2 - PXP_REG_HST_ZONE_PERMISSION_TABLE_SIZE) / pdev->params.vnics_per_port / 2;
3193                     port_base_aux_qzone = PORT_ID(pdev)* ((ETH_MAX_RX_CLIENTS_E2 - PXP_REG_HST_ZONE_PERMISSION_TABLE_SIZE)/PORT_MAX);
3194                     pdev->params.aux_fw_qzone_id = PXP_REG_HST_ZONE_PERMISSION_TABLE_SIZE + port_base_aux_qzone + VNIC_ID(pdev) * pdev->params.fw_aux_qzone_cnt;
3195                     pdev->params.base_fw_client_id = pdev->params.base_fw_ndsb + FUNC_ID(pdev) * MAX_NON_RSS_FW_CLIENTS;
3196                 }
3197                 else
3198                 {
3199                     pdev->params.base_fw_ndsb = IGU_BASE_NDSB(pdev) - (VNIC_ID(pdev) + 1) * LM_NUM_DSBS;
3200                     pdev->params.fw_aux_qzone_cnt = (ETH_MAX_RX_CLIENTS_E2 - PXP_REG_HST_ZONE_PERMISSION_TABLE_SIZE) / pdev->params.vnics_per_port;
3201                     pdev->params.aux_fw_qzone_id = PXP_REG_HST_ZONE_PERMISSION_TABLE_SIZE + VNIC_ID(pdev) * pdev->params.fw_aux_qzone_cnt;
3202                     pdev->params.base_fw_client_id = pdev->params.base_fw_ndsb + VNIC_ID(pdev) * MAX_NON_RSS_FW_CLIENTS;
3203                 }
3204                 pdev->params.fw_sb_cnt = LM_IGU_SB_CNT(pdev);
3205 #ifdef VF_INVOLVED
3206                 pdev->params.fw_sb_cnt = pdev->params.fw_sb_cnt + lm_pf_get_vf_available_igu_blocks(pdev);
3207                 if ((VNICS_PER_PORT(pdev) == 1) && (CHIP_PORT_MODE(pdev) == LM_CHIP_PORT_MODE_2))
3208                 {
3209                     pdev->params.fw_client_cnt = ETH_MAX_RX_CLIENTS_E2;
3210                 }
3211                 else
3212                 {
3213                     pdev->params.fw_client_cnt = pdev->params.fw_sb_cnt + MAX_NON_RSS_FW_CLIENTS;
3214                 }
3215 #else
3216                 pdev->params.fw_client_cnt = pdev->params.fw_sb_cnt + MAX_NON_RSS_FW_CLIENTS;
3217 #endif
3218                 pdev->params.fw_base_qzone_cnt = pdev->params.fw_sb_cnt;
3219                 base_fw_qzone_id = pdev->params.base_fw_ndsb;
3220                 pdev->params.max_pf_sb_cnt = LM_IGU_SB_CNT(pdev);
3221                 pdev->params.max_pf_fw_client_cnt = pdev->params.max_pf_sb_cnt + MAX_NON_RSS_FW_CLIENTS;
3222             }
3223             DbgMessage(pdev, WARN, "SB counts(from %d): %d rss, %d max(pf), %d fw ndsbs accessible\n",
3224                         pdev->params.base_fw_ndsb, pdev->params.sb_cnt, pdev->params.max_pf_sb_cnt, pdev->params.fw_sb_cnt);
3225             DbgBreakIf(pdev->params.sb_cnt > pdev->params.max_pf_sb_cnt);
3226             DbgBreakIf(pdev->params.max_pf_sb_cnt > pdev->params.fw_sb_cnt);
3227 
3228 //            pdev->params.base_fw_client_id = VNIC_ID(pdev) * pdev->params.fw_client_cnt;
3229             DbgMessage(pdev, WARN, "FW clients (from %d): %d max(pf), %d fw cliens accessible\n",
3230                         pdev->params.base_fw_client_id, pdev->params.max_pf_fw_client_cnt, pdev->params.fw_client_cnt);
3231             if (CHIP_IS_E2E3(pdev)) {
3232                 u8_t qz_idx;
3233                 for (qz_idx = 0; qz_idx < pdev->params.fw_base_qzone_cnt; qz_idx++)
3234                 {
3235                     pdev->params.fw_qzone_id[qz_idx] = base_fw_qzone_id + qz_idx;
3236 
3237                 }
3238                 DbgMessage(pdev, WARN, "%d base FW Q zone IDs from %d\n", pdev->params.fw_base_qzone_cnt, base_fw_qzone_id);
3239                 DbgMessage(pdev, WARN, "%d aux FW Q zone IDs from %d\n", pdev->params.fw_aux_qzone_cnt, pdev->params.aux_fw_qzone_id);
3240             }
3241 //            pdev->params.base_fw_client_id = VNIC_ID(pdev) * (pdev->params.sb_cnt + MAX_NON_RSS_FW_CLIENTS);
3242             /* For now, base_fw_qzone_id == base_fw_client_id, but this doesn't have to be the case... */
3243             /* qzone-id is relevant only for E2 and therefore it is ok that we use a */
3244             /* Todo - change once E2 client is added. */
3245 //            pdev->params.base_fw_qzone_id = pdev->params.base_fw_client_id + ETH_MAX_RX_CLIENTS_E1H*PORT_ID(pdev);
3246             /* E2 TODO: read how many sb each pf has...?? */
3247         } else if (IS_CHANNEL_VFDEV(pdev)) {
3248             pdev->params.sb_cnt = 16;
3249         } else {
3250             pdev->params.sb_cnt = 1;
3251         }
3252 
3253         pdev->params.max_rss_chains = ((IS_PFDEV(pdev) && IGU_U_NDSB_OFFSET(pdev)) ? min(IGU_U_NDSB_OFFSET(pdev),LM_SB_CNT(pdev)) : LM_SB_CNT(pdev));
3254         if (pdev->params.max_rss_chains > MAX_RSS_CHAINS)
3255         {
3256         pdev->params.max_rss_chains = MAX_RSS_CHAINS;
3257         }
3258 #ifndef EDIAG
3259         if(0 == pdev->params.max_rss_chains)
3260         {
3261             DbgBreakMsg("Zero isn't a valid value for pdev->params.max_rss_chains  ");
3262             return LM_STATUS_FAILURE;
3263         }
3264 #endif
3265         pdev->params.base_cam_offset = 0;
3266         /* set the clients cids that will be used by the driver */
3267         pdev->params.map_client_to_cid[LM_CLI_IDX_NDIS]  = 0;
3268         pdev->params.map_client_to_cid[LM_CLI_IDX_ISCSI] = i = LM_MAX_RSS_CHAINS(pdev);
3269         pdev->params.map_client_to_cid[LM_CLI_IDX_OOO]   = ++i;
3270         pdev->params.map_client_to_cid[LM_CLI_IDX_FCOE]  = ++i;
3271         pdev->params.map_client_to_cid[LM_CLI_IDX_FWD]   = ++i;
3272     pdev->params.start_mp_chain = ++i;
3273 
3274 //        pdev->params.map_client_to_cid[LM_CLI_IDX_RDMA]  = ++i;
3275         // FCoE is not supported in E1 and we have only 18 clients in E1
3276         // so we OOO client gets 'priority' over FCoE
3277         DbgBreakIf(pdev->params.map_client_to_cid[LM_CLI_IDX_OOO] > pdev->params.map_client_to_cid[LM_CLI_IDX_FCOE]);
3278 
3279         /* L4 RSS */
3280         pdev->params.l4_rss_chain_cnt = 1;
3281         pdev->params.l4_tss_chain_cnt = 1;
3282         /* set l4_rss base chain index to be the first one after l2 */
3283         pdev->params.l4_rss_base_chain_idx = 0;
3284         if (CHIP_IS_E1x(pdev))
3285         {
3286             pdev->params.l4_base_fw_rss_id = VNIC_ID(pdev) * pdev->params.sb_cnt;
3287    }
3288    else
3289         {
3290             pdev->params.l4_base_fw_rss_id = VNIC_ID(pdev);
3291         }
3292         /* master-pfdev needs to keep resources for its vfs, resource allocation is done first between
3293          * pfs and then each pf leaves itself 1 sb_cnt for enabling vfs. */
3294         pdev->params.eth_align_enable = 0;
3295         lm_init_cam_params(pdev);
3296 
3297         if((CHIP_REV_IS_SLOW(pdev)
3298 #ifdef DUMMY_MAC_FOR_VF
3299                 || IS_VFDEV(pdev)
3300 #endif
3301                 )
3302                 &&
3303                 (!(GET_FLAGS(pdev->hw_info.mf_info.flags,MF_INFO_VALID_MAC))))
3304         {
3305             pdev->params.mac_addr[0] = pdev->hw_info.mac_addr[0] = 0x00;
3306             pdev->params.mac_addr[1] = pdev->hw_info.mac_addr[1] = 0x50;
3307             pdev->params.mac_addr[2] = pdev->hw_info.mac_addr[2] = 0xc2;
3308             pdev->params.mac_addr[3] = pdev->hw_info.mac_addr[3] = 0x2c;
3309             pdev->params.mac_addr[4] = pdev->hw_info.mac_addr[4] = 0x70 + (IS_PFDEV(pdev) ? 0 : (1 + 64*PATH_ID(pdev) + ABS_VFID(pdev)));
3310             if (CHIP_IS_E1x(pdev))
3311             {
3312                 pdev->params.mac_addr[5] = pdev->hw_info.mac_addr[5] = 0x9a + 2 * FUNC_ID(pdev);
3313             }
3314             else
3315             {
3316                 pdev->params.mac_addr[5] = pdev->hw_info.mac_addr[5] = 0x9a + PATH_ID(pdev)*8 + PORT_ID(pdev)*4 + VNIC_ID(pdev)*2;
3317             }
3318 
3319             mm_memcpy(pdev->hw_info.iscsi_mac_addr, pdev->hw_info.mac_addr, 6);
3320             pdev->hw_info.iscsi_mac_addr[5]++;
3321             mm_memcpy(pdev->hw_info.fcoe_mac_addr, pdev->hw_info.iscsi_mac_addr, 6);
3322             pdev->hw_info.fcoe_mac_addr[5]++;
3323             lm_fcoe_set_default_wwns(pdev);
3324         }
3325         else
3326         {
3327             pdev->params.mac_addr[0] = pdev->hw_info.mac_addr[0];
3328             pdev->params.mac_addr[1] = pdev->hw_info.mac_addr[1];
3329             pdev->params.mac_addr[2] = pdev->hw_info.mac_addr[2];
3330             pdev->params.mac_addr[3] = pdev->hw_info.mac_addr[3];
3331             pdev->params.mac_addr[4] = pdev->hw_info.mac_addr[4];
3332             pdev->params.mac_addr[5] = pdev->hw_info.mac_addr[5];
3333         }
3334         if(CHIP_REV_IS_EMUL(pdev))
3335         {
3336             DbgMessage(pdev, INFORMi, "Emulation is detected.\n");
3337             pdev->params.test_mode |= TEST_MODE_IGNORE_SHMEM_SIGNATURE;
3338             pdev->params.test_mode |= TEST_MODE_LOG_REG_ACCESS;
3339             //pdev->params.test_mode |= TEST_MODE_NO_MCP;
3340             DbgMessage(pdev, INFORMi , "test mode is 0x%x \n",pdev->params.test_mode);
3341         }
3342         else
3343         {
3344             DbgMessage(pdev, INFORMi, "ASIC is detected.\n");
3345         }
3346         if (!pdev->hw_info.mcp_detected)
3347         {
3348             pdev->params.test_mode |= TEST_MODE_NO_MCP;
3349         }
3350         flow_control = (pdev->hw_info.link_config[ELINK_INT_PHY] & PORT_FEATURE_FLOW_CONTROL_MASK);
3351 
3352         switch (flow_control)
3353         {
3354         case PORT_FEATURE_FLOW_CONTROL_AUTO:
3355             pdev->params.flow_ctrl_cap = LM_FLOW_CONTROL_AUTO_PAUSE;
3356         break;
3357         case PORT_FEATURE_FLOW_CONTROL_TX:
3358             pdev->params.flow_ctrl_cap = LM_FLOW_CONTROL_TRANSMIT_PAUSE;
3359         break;
3360         case PORT_FEATURE_FLOW_CONTROL_RX:
3361             pdev->params.flow_ctrl_cap = LM_FLOW_CONTROL_RECEIVE_PAUSE;
3362         break;
3363         case PORT_FEATURE_FLOW_CONTROL_BOTH:
3364             pdev->params.flow_ctrl_cap = LM_FLOW_CONTROL_TRANSMIT_PAUSE | LM_FLOW_CONTROL_RECEIVE_PAUSE;
3365         break;
3366         case PORT_FEATURE_FLOW_CONTROL_NONE:
3367             pdev->params.flow_ctrl_cap = LM_FLOW_CONTROL_NONE;
3368         break;
3369         default:
3370             pdev->params.flow_ctrl_cap = LM_FLOW_CONTROL_NONE;
3371         break;
3372         }
3373 
3374         /*
3375          * We don't know (yet...) if the PHY supportes EEE - so we cannot set params
3376          * to reflect this info.
3377          */
3378 
3379         /* L2 FW Flow control */
3380         // cq57766
3381         // if this static assert fails consider adding the new mode to the if
3382         // and read the l2_fw_flow_ctrl from the shmem in the new mode also
3383         ASSERT_STATIC(MAX_MF_MODE == 4);
3384         if ((pdev->hw_info.mf_info.mf_mode == SINGLE_FUNCTION) ||
3385             (pdev->hw_info.mf_info.mf_mode == MULTI_FUNCTION_SD) ||
3386             (CHIP_IS_E1x(pdev)))
3387         {
3388             // l2_fw_flow_ctrl is read from the shmem in multi-function mode in E2 and above.
3389             // In all other cases this parameter is read from the registry.
3390             // We read this parameter from the registry in E1.5 multi-function since 57711 boot code does not have the struct func_ext_cfg
3391             pdev->params.l2_fw_flow_ctrl = 0;
3392         }
3393         pdev->params.l4_fw_flow_ctrl = 0;
3394         pdev->params.fw_stats_init_value = TRUE;
3395 
3396         pdev->params.mf_mode = pdev->hw_info.mf_info.mf_mode;
3397         if (pdev->params.mf_mode == MULTI_FUNCTION_SD)
3398         {
3399             pdev->params.sd_mode = pdev->hw_info.mf_info.sd_mode;
3400         }
3401 
3402     }
3403     else
3404     {
3405         /* Make sure the parameter values are within range. */
3406         param = param_list;
3407         while(param->offset)
3408         {
3409             if(param->min != 0 || param->max != 0)
3410             {
3411                 if(PARAM_VAL(pdev, param) < param->min ||
3412                     PARAM_VAL(pdev, param) > param->max)
3413                 {
3414                     if(CHIP_REV_IS_FPGA(pdev))
3415                     {
3416                         SET_PARAM_VAL(pdev, param, param->fpga_default);
3417                     }
3418                     else if(CHIP_REV_IS_EMUL(pdev))
3419                     {
3420                         SET_PARAM_VAL(pdev, param, param->emulation_default);
3421                     }
3422                     else
3423                     {
3424                         SET_PARAM_VAL(pdev, param, param->asic_default);
3425                     }
3426                 }
3427             }
3428             param++;
3429         }
3430         /* calculate context_line_size context_waste_size */
3431         // TODO calculate number of context lines in alocation page.
3432             csize = max(sizeof(struct eth_context),sizeof(struct toe_context));
3433             //csize = max(sizeof(struct rdma_context),csize);
3434             csize = max(sizeof(struct iscsi_context),csize);
3435             DbgBreakIf(csize>1024);
3436         /* Check for a valid mac address. */
3437         if((pdev->params.mac_addr[0] == 0 &&
3438             pdev->params.mac_addr[1] == 0 &&
3439             pdev->params.mac_addr[2] == 0 &&
3440             pdev->params.mac_addr[3] == 0 &&
3441             pdev->params.mac_addr[4] == 0 &&
3442             pdev->params.mac_addr[5] == 0) || (pdev->params.mac_addr[0] & 1))
3443         {
3444             DbgMessage(pdev, WARNi, "invalid MAC number.\n");
3445             pdev->params.mac_addr[0] = pdev->hw_info.mac_addr[0];
3446             pdev->params.mac_addr[1] = pdev->hw_info.mac_addr[1];
3447             pdev->params.mac_addr[2] = pdev->hw_info.mac_addr[2];
3448             pdev->params.mac_addr[3] = pdev->hw_info.mac_addr[3];
3449             pdev->params.mac_addr[4] = pdev->hw_info.mac_addr[4];
3450             pdev->params.mac_addr[5] = pdev->hw_info.mac_addr[5];
3451         }
3452         if (CHIP_IS_E1(pdev))
3453         {
3454             if ((pdev->params.l2_fw_flow_ctrl == 1) || (pdev->params.l4_fw_flow_ctrl == 1))
3455             {
3456                 DbgMessage(pdev, WARNi, "L2 FW Flow control not supported on E1\n");
3457                 pdev->params.l2_fw_flow_ctrl = 0;
3458                 pdev->params.l4_fw_flow_ctrl = 0;
3459             }
3460         }
3461     }
3462 
3463     /* init l2 client conn param with default mtu values */
3464     for (i = 0; i < ARRSIZE(pdev->params.l2_cli_con_params); i++)
3465     {
3466         lm_cli_idx_t lm_cli_idx = LM_CHAIN_IDX_CLI(pdev, i);
3467         ASSERT_STATIC( ARRSIZE(pdev->params.l2_rx_desc_cnt) == ARRSIZE(pdev->params.mtu));
3468         if(  lm_cli_idx >= ARRSIZE(pdev->params.l2_rx_desc_cnt))
3469         {
3470             // in case lm_cli_idx is above boundries
3471             // it means that is should not be used (currently expected in MF mode)
3472             // we skip the iteration
3473             continue;
3474         }
3475         pdev->params.l2_cli_con_params[i].mtu         = pdev->params.mtu[lm_cli_idx];
3476 
3477         if(i < (LM_SB_CNT(pdev) + MAX_NON_RSS_CHAINS))
3478         {
3479             pdev->params.l2_cli_con_params[i].num_rx_desc = pdev->params.l2_rx_desc_cnt[lm_cli_idx];
3480             pdev->params.l2_cli_con_params[i].attributes  = LM_CLIENT_ATTRIBUTES_RX | LM_CLIENT_ATTRIBUTES_TX | LM_CLIENT_ATTRIBUTES_REG_CLI;
3481         }
3482         else
3483         {
3484             pdev->params.l2_cli_con_params[i].attributes  = LM_CLIENT_ATTRIBUTES_TX;
3485         }
3486     }
3487     return LM_STATUS_SUCCESS;
3488 } /* lm_init_params */
3489 
3490 /*******************************************************************************
3491  * Description:
3492  *
3493  * Return:
3494  ******************************************************************************/
3495 lm_status_t
lm_get_dev_info(lm_device_t * pdev)3496 lm_get_dev_info(
3497     lm_device_t *pdev)
3498 {
3499     lm_status_t lm_status = LM_STATUS_SUCCESS;
3500 
3501     DbgMessage(pdev, INFORMi , "### lm_get_dev_info\n");
3502 
3503     // initialize "product_version" to 0xffffffff so all platforms will have invalid values (but Windows that will update it later)
3504     mm_memset( pdev->product_version, 0xff, sizeof(pdev->product_version) );
3505 
3506     lm_status = lm_get_pcicfg_info(pdev);
3507     if(lm_status != LM_STATUS_SUCCESS)
3508     {
3509         return lm_status;
3510     }
3511 
3512     lm_status = lm_get_bars_info(pdev);
3513     if(lm_status != LM_STATUS_SUCCESS)
3514     {
3515         return lm_status;
3516     }
3517     if (!IS_CHANNEL_VFDEV(pdev)) {
3518         lm_status = lm_get_chip_id_and_mode(pdev);
3519         if(lm_status != LM_STATUS_SUCCESS)
3520         {
3521             return lm_status;
3522         }
3523     }
3524     if (IS_PFDEV(pdev)) {
3525         // Get function num using me register
3526         lm_status = lm_get_function_num(pdev);
3527         if (lm_status != LM_STATUS_SUCCESS) {
3528             return lm_status;
3529         }
3530         // initialize pointers to init arrays (can only do this after we know which chip we are...)
3531         // We want to do this here to enable IRO access before driver load (ediag/lediag) this is only done
3532         // for PFs, VFs use PFDEV to access IRO
3533         if ( lm_set_init_arrs(pdev) != 0 ) {
3534             DbgMessage(pdev, FATAL, "Unknown chip revision\n");
3535             return LM_STATUS_UNKNOWN_ADAPTER;
3536         }
3537     } else {
3538             /* For VF, we also get the vf-id here... since we need it from configuration space */
3539 #ifdef VF_INVOLVED
3540         if (IS_VFDEV(pdev))
3541         {
3542             lm_vf_get_vf_id(pdev);
3543         }
3544 #endif
3545     }
3546 
3547 #ifdef __LINUX
3548     if (lm_is_function_after_flr(pdev))
3549     {
3550         if (IS_PFDEV(pdev)) {
3551             lm_status = lm_cleanup_after_flr(pdev);
3552             if(lm_status != LM_STATUS_SUCCESS)
3553             {
3554                 return lm_status;
3555             }
3556         } else {
3557         /*  8.  Verify that the transaction-pending bit of each of the function in the Device Status Register in the PCIe is cleared. */
3558 
3559 #ifdef __LINUX
3560             u32_t pcie_caps_offset = mm_get_cap_offset(pdev, PCI_CAP_PCIE);
3561             if (pcie_caps_offset != 0 && pcie_caps_offset != 0xFFFFFFFF) {
3562                 u32_t dev_control_and_status = 0xFFFFFFFF;
3563                 mm_read_pci(pdev, pcie_caps_offset + PCIE_DEV_CTRL, &dev_control_and_status);
3564                 DbgMessage(pdev, FATAL,"Device Control&Status of PCIe caps is %x\n",dev_control_and_status);
3565                 if (dev_control_and_status & (PCIE_DEV_STATUS_PENDING_TRANSACTION << 16)) {
3566                     DbgBreak();
3567                 }
3568             }
3569 #else
3570             DbgMessage(pdev, FATAL, "Function mm_get_cap_offset is not implemented yet\n");
3571             DbgBreak();
3572 #endif
3573             lm_fl_reset_clear_inprogress(pdev);
3574         }
3575     }
3576 #endif
3577 
3578     if (IS_CHANNEL_VIRT_MODE_MASTER_PFDEV(pdev)) {
3579         pdev->params.max_eth_including_vfs_conns = 1 << (LM_VF_MAX_RVFID_SIZE + LM_VF_CID_WND_SIZE(pdev) + 1);
3580     } else if (IS_PFDEV(pdev)) {
3581         pdev->params.max_eth_including_vfs_conns = MAX_VF_ETH_CONS;
3582         // Registry parameters are read in this stage.
3583         // As a result pdev->params.is_dcb_ndis_mp_en isn't valid yet.
3584         if(IS_DCB_SUPPORTED_BY_CHIP(pdev))
3585         {
3586             // Add DCB multiple connections
3587 #ifdef _VBD_
3588             pdev->params.max_eth_including_vfs_conns += 3 * MAX_HW_CHAINS + MAX_NON_RSS_CHAINS;
3589 #else
3590             pdev->params.max_eth_including_vfs_conns += MAX_ETH_CONS;
3591 #endif
3592         }
3593         else
3594         {
3595 #ifdef _VBD_
3596             pdev->params.max_eth_including_vfs_conns += MAX_ETH_REG_CHAINS;
3597 #else
3598             pdev->params.max_eth_including_vfs_conns += MAX_ETH_REG_CONS;
3599 #endif
3600         }
3601     }
3602     else
3603     {
3604         pdev->params.max_eth_including_vfs_conns = MAX_RSS_CHAINS;
3605     }
3606     if (IS_PFDEV(pdev)) {
3607         lm_status = lm_get_sriov_info(pdev);
3608         if (lm_status != LM_STATUS_SUCCESS) {
3609             return lm_status;
3610         }
3611         lm_status = lm_get_nvm_info(pdev);
3612         if (lm_status != LM_STATUS_SUCCESS) {
3613             return lm_status;
3614         }
3615         lm_status = lm_get_shmem_info(pdev);
3616         if (lm_status != LM_STATUS_SUCCESS) {
3617             return lm_status;
3618         }
3619 
3620     } else if (IS_CHANNEL_VFDEV(pdev)) { //TODO check for basic vf
3621         pdev->hw_info.mf_info.multi_vnics_mode = 0;
3622         pdev->hw_info.mf_info.vnics_per_port   = 1;
3623         pdev->hw_info.mf_info.ext_id            = 0xffff; /* invalid ovlan */ /* TBD - E1H: - what is the right value for Cisco? */
3624         pdev->hw_info.mcp_detected = FALSE;
3625         pdev->hw_info.chip_id = CHIP_NUM_5712E;
3626         pdev->hw_info.max_port_conns =  log2_align(MAX_ETH_CONS);
3627         pdev->debug_info.ack_en[0] = 1;
3628     }
3629 
3630 #ifdef VF_INVOLVED
3631     if (IS_VFDEV(pdev)) {
3632         lm_vf_enable_vf(pdev);
3633     }
3634 #endif
3635     pdev->ver_num =
3636         (LM_DRIVER_MAJOR_VER << 24) |
3637         (LM_DRIVER_MINOR_VER << 16) |
3638         (LM_DRIVER_FIX_NUM   << 8)  |
3639          LM_DRIVER_ENG_NUM ;
3640     mm_build_ver_string(pdev);
3641     // for debugging only (no other use)
3642     pdev->ver_num_fw = (BCM_5710_FW_MAJOR_VERSION << 24) |
3643                        (BCM_5710_FW_MINOR_VERSION << 16) |
3644                        (BCM_5710_FW_REVISION_VERSION<<8) |
3645                        (BCM_5710_FW_ENGINEERING_VERSION) ;
3646     /* get vnic parameters */
3647     pdev->params.vnics_per_port = pdev->hw_info.mf_info.vnics_per_port;
3648     pdev->params.ovlan = VALID_OVLAN(OVLAN(pdev)) ? OVLAN(pdev) : 0; // TBD: verify it's the right value (with OfirH)
3649     pdev->params.multi_vnics_mode = pdev->hw_info.mf_info.multi_vnics_mode;
3650     pdev->params.path_has_ovlan = pdev->hw_info.mf_info.path_has_ovlan;
3651 
3652     if IS_MULTI_VNIC(pdev)
3653     {
3654         lm_cmng_calc_params(pdev);
3655     }
3656 
3657     if (IS_PFDEV(pdev))
3658     {
3659         // clc params
3660         init_link_params(pdev);
3661     }
3662 
3663     if (IS_CHANNEL_VFDEV(pdev))
3664     {
3665         pdev->hw_info.intr_blk_info.blk_type = INTR_BLK_IGU;
3666         pdev->hw_info.intr_blk_info.blk_mode = INTR_BLK_MODE_NORM;
3667         pdev->hw_info.intr_blk_info.access_type = INTR_BLK_ACCESS_IGUMEM;
3668     }
3669     else
3670     {
3671         lm_status = lm_get_intr_blk_info(pdev);
3672         if(lm_status != LM_STATUS_SUCCESS)
3673         {
3674             return lm_status;
3675         }
3676     }
3677 
3678     lm_status = lm_init_params(pdev, 0);
3679     if(lm_status != LM_STATUS_SUCCESS)
3680     {
3681         return lm_status;
3682     }
3683 
3684     lm_status = lm_mcp_cmd_init(pdev);
3685     if( LM_STATUS_SUCCESS != lm_status )
3686     {
3687         // Ediag may want to update the BC version. Don't fail lm_get_dev_info because of lm_mcp_cmd_init
3688         // in no condition.
3689         DbgMessage(pdev, FATAL, "lm_get_shmem_info: mcp_cmd_init failed. lm_status=0x%x\n", lm_status);
3690     }
3691 
3692     if (CHIP_PORT_MODE(pdev) == LM_CHIP_PORT_MODE_4)
3693     {
3694         /* We're a single-function port on a mult-function path in a 4-port-mode environment... we need to support 1G */
3695         if (pdev->params.path_has_ovlan && !pdev->params.multi_vnics_mode)
3696         {
3697             DbgMessage(pdev, WARN, "func_id = %d Setting link speed to 1000MBPS\n", ABS_FUNC_ID(pdev));
3698             SET_MEDIUM_SPEED(pdev->params.req_medium, LM_MEDIUM_SPEED_1000MBPS);
3699         }
3700     }
3701 
3702     /* Override the defaults with user configurations. */
3703     lm_status = mm_get_user_config(pdev);
3704     if(lm_status != LM_STATUS_SUCCESS)
3705     {
3706         return lm_status;
3707     }
3708     lm_status = lm_init_params(pdev, 1);
3709     if(lm_status != LM_STATUS_SUCCESS)
3710     {
3711         return lm_status;
3712     }
3713     DbgMessage(pdev, INFORMi , "### lm_get_dev_info exit\n");
3714     return LM_STATUS_SUCCESS;
3715 } /* lm_get_dev_info */
3716 
3717 /*
3718  *Function Name: lm_get_port_id_from_func_abs
3719  *
3720  *Parameters:
3721  *
3722  *Description:
3723  *  returns the port ID according to the func_abs_id
3724  * E1/E1.5:
3725  * Port0: 0,2,4,6
3726  * Port1: 1,3,5,7
3727  *
3728  * E2/E32P
3729  * Port0: 0,1,2,3,4,5,6,7
3730  *
3731  * E34P
3732  * Port0: 0,1,4,5
3733  * Port1: 2,3,6,7
3734  *
3735  *Returns: u8_t port_id
3736  *
3737  */
lm_get_port_id_from_func_abs(const u32_t chip_num,const lm_chip_port_mode_t lm_chip_port_mode,const u8_t abs_func)3738 u8_t lm_get_port_id_from_func_abs( const u32_t chip_num,  const lm_chip_port_mode_t lm_chip_port_mode, const u8_t abs_func )
3739 {
3740     u8_t port_id     = 0xff;
3741     u8_t modulus_res = 0;
3742 
3743     do
3744     {
3745         if( CHIP_IS_E1x_PARAM( chip_num ) )
3746         {
3747             port_id = abs_func % PORT_MAX;
3748             break;
3749         }
3750 
3751         switch( lm_chip_port_mode )
3752         {
3753         case LM_CHIP_PORT_MODE_2:
3754             {
3755                 // we expect here only E2 or E3
3756                 DbgBreakIf( CHIP_IS_E1x_PARAM( chip_num ) );
3757                 port_id = 0;
3758             }
3759             break;
3760 
3761         case LM_CHIP_PORT_MODE_4:
3762             {
3763                 modulus_res = abs_func % 4;
3764                 switch (modulus_res)
3765                 {
3766                 case 0:
3767                 case 1:
3768                     port_id = 0;
3769                     break;
3770                 case 2:
3771                 case 3:
3772                     port_id = 1;
3773                     break;
3774                 default:
3775                     break;
3776                 }
3777             }
3778             break;
3779 
3780         default:
3781             DbgBreakIf(TRUE);
3782             break;
3783         } // switch lm_chip_port_mode
3784 
3785     }while(0);
3786 
3787     return port_id;
3788 } /* lm_get_port_id_from_func_abs */
3789 
3790 /*
3791  *Function Name: lm_get_abs_func_vector
3792  *
3793  *Parameters:
3794  *
3795  *Description:
3796  *  returns vector of abs_func id's upon parameters
3797  *
3798  *Returns: u32_t abs_func_vector
3799  *
3800  */
lm_get_abs_func_vector(const u32_t chip_num,const lm_chip_port_mode_t chip_port_mode,const u8_t b_multi_vnics_mode,const u8_t path_id)3801 u8_t lm_get_abs_func_vector( const u32_t chip_num,  const lm_chip_port_mode_t chip_port_mode, const u8_t b_multi_vnics_mode, const u8_t path_id )
3802 {
3803     u8_t abs_func_vector = 0;
3804 
3805     // TODO VF for T7.0
3806 
3807 /*
3808     The following table is mapping between abs func, ports and paths
3809 
3810     |-----------------------------------------------|
3811     |[#]| CHIP & Mode | PATH(s) | Port(s) | Func(s) |
3812     |---|-------------|---------|---------|---------|
3813     |[1]| E1.0 (SF)   |   (0)   |   0,1   |  (0,1)  |
3814     |   | E1.5  SF    |         |   0,1   |  (0,1)  | (port is same as func)
3815     |---|-------------|---------|---------|---------|
3816     |[2]| E1.5 MF     |   (0)   |   0,1   |   0-7   | 0,1,2,3,4,5,6,7 (port is %2 of func)
3817     |---|-------------|---------|---------|---------|
3818     |[3]| E2/E32P SF  |   0,1   |   0     |   --->  | (Path 0) 0        | (Path 1) 1
3819     |---|-------------|---------|---------|---------|
3820     |[4]| E2/E32P MF  |   0,1   |   0     |   --->  | (Path 0) 0,2,4,6  | (Path 1) 1,3,5,7
3821     |---|-------------|---------|---------|---------|
3822     |[5]| E34P SF     |   0,1   |   0,1   |   --->  | (Path 0) 0:port0 2:port1     | (Path 1) 1:port0 3:port1
3823     |---|-------------|---------|---------|---------|
3824     |[6]| E34P MF     |   0,1   |   0,1   |   --->  | (Path 0) 0,4:port0 2,6:port1 | (Path 1) 1,5:port0 3,7:port1 (57840)
3825     |---|-------------|---------|---------|---------|
3826     |[7]| E34P MF/SF  |   0,1   |   0,1   |   --->  | (Path 0) 0,4:port0 2:port1   | (Path 1) 1,5:port0 3:port1 (57800)
3827     |---|-------------|---------|---------|---------|
3828 */
3829     do
3830     {
3831         // [1]
3832         if( CHIP_IS_E1x_PARAM(chip_num) && !b_multi_vnics_mode )
3833         {
3834             SET_BIT( abs_func_vector, 0 );
3835             SET_BIT( abs_func_vector, 1 );
3836             break;
3837         }
3838 
3839         // [2]
3840         if( CHIP_IS_E1H_PARAM(chip_num) && b_multi_vnics_mode )
3841         {
3842             SET_BIT( abs_func_vector, 0 );
3843             SET_BIT( abs_func_vector, 1 );
3844             SET_BIT( abs_func_vector, 2 );
3845             SET_BIT( abs_func_vector, 3 );
3846             SET_BIT( abs_func_vector, 4 );
3847             SET_BIT( abs_func_vector, 5 );
3848             SET_BIT( abs_func_vector, 6 );
3849             SET_BIT( abs_func_vector, 7 );
3850             break;
3851         }
3852 
3853         // If we got here chip should not be ealier than E2
3854         DbgBreakIf( CHIP_IS_E1x_PARAM(chip_num) );
3855 
3856         // [3] [4] [5] [6]
3857         switch ( chip_port_mode )
3858         {
3859         case LM_CHIP_PORT_MODE_2:
3860             {
3861                 // we expect here only E2 or E3
3862                 DbgBreakIf( !CHIP_IS_E2_PARAM(chip_num) && !CHIP_IS_E3_PARAM(chip_num) );
3863 
3864                 if( b_multi_vnics_mode )
3865                 {
3866                     // [4]
3867                     SET_BIT( abs_func_vector, (0 + path_id) );
3868                     SET_BIT( abs_func_vector, (2 + path_id) );
3869                     SET_BIT( abs_func_vector, (4 + path_id) );
3870                     SET_BIT( abs_func_vector, (6 + path_id) );
3871                     break;
3872                 }
3873                 else
3874                 {
3875                     // [3]
3876                     SET_BIT( abs_func_vector, path_id );
3877                     break;
3878                 }
3879             } // LM_CHIP_PORT_MODE_2
3880             break;
3881 
3882 
3883         case LM_CHIP_PORT_MODE_4:
3884             {
3885                 if( b_multi_vnics_mode )
3886                 {
3887                     // [6]
3888                     if (chip_num != CHIP_NUM_57800)
3889                     {
3890                         SET_BIT( abs_func_vector, (0 + path_id) );
3891                         SET_BIT( abs_func_vector, (2 + path_id) );
3892                         SET_BIT( abs_func_vector, (4 + path_id) );
3893                         SET_BIT( abs_func_vector, (6 + path_id) );
3894 
3895                     }
3896                     // [7] In 57800 if we are multi function the other port can only be single function
3897                     else
3898                     {
3899                         SET_BIT( abs_func_vector, (0 + path_id) );
3900                         SET_BIT( abs_func_vector, (2 + path_id) );
3901                         SET_BIT( abs_func_vector, (4 + path_id) );
3902                     }
3903                     break;
3904                 }
3905                 else
3906                 {
3907                     // [5]
3908                     if (chip_num != CHIP_NUM_57800)
3909                     {
3910                         SET_BIT( abs_func_vector, (0 + path_id) );
3911                         SET_BIT( abs_func_vector, (2 + path_id) );
3912                     }
3913                     // [7] We can't really know what's on the other port, so for this case where we are
3914                     //     in 57800 single function, we assume multi-function and access all the functions
3915                     //     so this might be case [5] but we can't know this.
3916                     else
3917                     {
3918                         SET_BIT( abs_func_vector, (0 + path_id) );
3919                         SET_BIT( abs_func_vector, (2 + path_id) );
3920                         SET_BIT( abs_func_vector, (4 + path_id) );
3921                     }
3922                     break;
3923                 }
3924             } // LM_CHIP_PORT_MODE_4
3925             break;
3926 
3927         default:
3928             {
3929                 DbgBreakIf(TRUE);
3930                 break;
3931             }
3932         } // CHIP_PORT_MODE
3933 
3934     }while(0);
3935 
3936     return abs_func_vector;
3937 } /* lm_get_abs_func_vector */
3938 
lm_verify_validity_map(lm_device_t * pdev)3939 lm_status_t lm_verify_validity_map(lm_device_t *pdev)
3940 {
3941     u64_t        wait_cnt       = 0 ;
3942     u64_t        wait_cnt_limit = 200000; // 4 seconds (ASIC)
3943     u32_t        val            = 0;
3944     lm_status_t  lm_status      = LM_STATUS_FAILURE ;
3945     if ( CHK_NULL(pdev) )
3946     {
3947         return LM_STATUS_INVALID_PARAMETER ;
3948     }
3949     wait_cnt_limit*= (u64_t)(pdev->vars.clk_factor) ;
3950     for(wait_cnt = 0; wait_cnt < wait_cnt_limit; wait_cnt++)
3951     {
3952         LM_SHMEM_READ(pdev,OFFSETOF(shmem_region_t, validity_map[PORT_ID(pdev)]),&val);
3953         // check that shared memory is valid.
3954         if((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) == (SHR_MEM_VALIDITY_DEV_INFO|SHR_MEM_VALIDITY_MB))
3955         {
3956             lm_status = LM_STATUS_SUCCESS ;
3957             break;
3958         }
3959         mm_wait(pdev, 20);
3960     }
3961     DbgMessage(pdev, INFORMi, "lm_verify_validity_map: shmem signature %d\n",val);
3962     return lm_status ;
3963 }
3964 
3965 
3966 lm_status_t
lm_set_cam_params(struct _lm_device_t * pdev,u32_t mac_requestors_mask,u32_t base_offset_in_cam_table,u32_t cam_size,u32_t mma_size,u32_t mc_size)3967 lm_set_cam_params(struct _lm_device_t * pdev,
3968                   u32_t mac_requestors_mask,
3969                   u32_t base_offset_in_cam_table,
3970                   u32_t cam_size,
3971                   u32_t mma_size,
3972                   u32_t mc_size)
3973 {
3974     lm_status_t lm_status =  LM_STATUS_SUCCESS;
3975     if (IS_VFDEV(pdev)) {
3976         return LM_STATUS_FAILURE;
3977     }
3978     if (base_offset_in_cam_table != LM_KEEP_CURRENT_CAM_VALUE) {
3979         pdev->params.base_offset_in_cam_table = (u8_t)base_offset_in_cam_table;
3980     }
3981     if (cam_size != LM_KEEP_CURRENT_CAM_VALUE) {
3982         pdev->params.cam_size = (u8_t)cam_size;
3983     }
3984     if (mc_size != LM_KEEP_CURRENT_CAM_VALUE) {
3985         if (CHIP_IS_E1(pdev)) {
3986             pdev->params.mc_table_size[LM_CLI_IDX_NDIS]  =(u8_t) mc_size;
3987         } else {
3988             pdev->params.mc_table_size[LM_CLI_IDX_FCOE]  = (u8_t)mc_size;
3989         }
3990     }
3991 
3992     return lm_status;
3993 } /* lm_set_cam_params */
3994 
3995 /*******************************************************************************
3996  * Description:
3997  *
3998  * Return:
3999  ******************************************************************************/
lm_cmng_calc_params(lm_device_t * pdev)4000 void lm_cmng_calc_params(lm_device_t* pdev )
4001 {
4002     u8_t vnic = 0;
4003     DbgBreakIf(!IS_MULTI_VNIC(pdev));
4004     for (vnic = 0; vnic < MAX_VNIC_NUM; vnic++)
4005     {
4006         if (GET_FLAGS(pdev->hw_info.mf_info.func_mf_cfg , FUNC_MF_CFG_FUNC_HIDE))
4007         {
4008             pdev->params.min_bw[vnic] = 0;
4009             pdev->params.max_bw[vnic] = 0;
4010         }
4011         else
4012         {
4013             pdev->params.min_bw[vnic] = pdev->hw_info.mf_info.min_bw[vnic];
4014             pdev->params.max_bw[vnic] = pdev->hw_info.mf_info.max_bw[vnic];
4015         }
4016     }
4017 } /* lm_cmng_calc_params */
4018 
4019 /**
4020  * @description
4021  * Calculates BW according to current linespeed and MF
4022  * configuration  of the function in Mbps.
4023  * @param pdev
4024  * @param link_speed - Port rate in Mbps.
4025  * @param vnic
4026  *
4027  * @return u16
4028  * Return the max BW of the function in Mbps.
4029  */
4030 u16_t
lm_get_max_bw(IN const lm_device_t * pdev,IN const u32_t link_speed,IN const u8_t vnic)4031 lm_get_max_bw(IN const lm_device_t  *pdev,
4032               IN const u32_t        link_speed,
4033               IN const u8_t         vnic)
4034 {
4035     u16_t  max_bw   = 0;
4036 
4037     DbgBreakIf(0 == IS_MULTI_VNIC(pdev));
4038 
4039     //global vnic counter
4040     if(IS_MF_SD_MODE(pdev) || IS_MF_AFEX_MODE(pdev))
4041     {
4042         // SD max BW in 100Mbps
4043         max_bw = pdev->params.max_bw[vnic]*100;
4044     }
4045     else
4046     {
4047         // SI max BW in percentage from the link speed.
4048         DbgBreakIf(FALSE == IS_MF_SI_MODE(pdev));
4049         max_bw = (link_speed * pdev->params.max_bw[vnic])/100;
4050     }
4051     return max_bw;
4052 }
4053 
lm_check_if_pf_assigned_to_vm(struct _lm_device_t * pdev)4054 u8_t lm_check_if_pf_assigned_to_vm(struct _lm_device_t *pdev)
4055 {
4056     u8_t b_assigned_to_vm = FALSE;
4057 
4058     switch (pdev->hw_info.pci_cfg_trust)
4059     {
4060         case PCI_CFG_NOT_TESTED_FOR_TRUST:
4061             break;
4062         case PCI_CFG_NOT_TRUSTED:
4063             b_assigned_to_vm = TRUE;
4064             break;
4065         case PCI_CFG_TRUSTED:
4066             b_assigned_to_vm = FALSE;
4067             break;
4068     }
4069     return b_assigned_to_vm;
4070 }
4071 
lm_is_fw_version_valid(struct _lm_device_t * pdev)4072 u8_t lm_is_fw_version_valid(struct _lm_device_t *pdev)
4073 {
4074     u8_t is_fw_valid = FALSE;
4075     u32_t drv_fw_ver = (BCM_5710_FW_MAJOR_VERSION) |
4076                        (BCM_5710_FW_MINOR_VERSION << 8) |
4077                        (BCM_5710_FW_REVISION_VERSION << 16) |
4078                        (BCM_5710_FW_ENGINEERING_VERSION  << 24) ;
4079     u32_t real_fw_ver = REG_RD(pdev,0x2c0000); /* Read acitve FW version from 1st DWORD of XSTORM params*/
4080     u32_t fw_valid_mask;
4081 
4082     fw_valid_mask = SWAP_BYTES32(pdev->params.fw_valid_mask);
4083     is_fw_valid = (((drv_fw_ver ^ real_fw_ver) & fw_valid_mask) == 0);
4084     return (is_fw_valid);
4085 }
4086 
4087 /*
4088  * Support for NSCI get OS driver version CQ70040
4089  */
4090 
4091 /*Descripion: Write the client driver version
4092 *              to the shmem2 region
4093 */
4094 lm_status_t
lm_set_cli_drv_ver_to_shmem(struct _lm_device_t * pdev)4095 lm_set_cli_drv_ver_to_shmem(struct _lm_device_t *pdev)
4096 {
4097     u32_t               drv_ver_offset      = OFFSETOF(shmem2_region_t,func_os_drv_ver);
4098     u32_t               offset              = 0;
4099     lm_status_t         lm_status           = LM_STATUS_SUCCESS; //  Status is always SUCCESS now
4100     u32_t               shmem2_size         = 0;
4101     u32_t               index               = 0;
4102 
4103     if (IS_VFDEV(pdev))
4104     {
4105         return LM_STATUS_SUCCESS;
4106     }
4107 
4108     ASSERT_STATIC( sizeof(pdev->lm_cli_drv_ver_to_shmem.cli_drv_ver) == sizeof(struct os_drv_ver) );
4109 
4110     offset = drv_ver_offset + (pdev->params.pfunc_mb_id * sizeof(pdev->lm_cli_drv_ver_to_shmem.cli_drv_ver));
4111 
4112     DbgMessage(pdev, WARN,"offset= %d \n", offset);
4113 
4114     if (pdev->hw_info.shmem_base2 != 0)
4115     {
4116         LM_SHMEM2_READ (pdev, OFFSETOF(shmem2_region_t,size), &shmem2_size);
4117         if (shmem2_size > offset)
4118         {
4119             for (index = 0; index < ARRSIZE(pdev->lm_cli_drv_ver_to_shmem.cli_drv_ver.versions); index++)
4120             {
4121                 LM_SHMEM2_WRITE(pdev, offset, pdev->lm_cli_drv_ver_to_shmem.cli_drv_ver.versions[index]);
4122                 offset+= sizeof( pdev->lm_cli_drv_ver_to_shmem.cli_drv_ver.versions[index] );
4123             }
4124         }
4125     }
4126 
4127    return lm_status;
4128 }
4129 
lm_is_mac_locally_administrated(struct _lm_device_t * pdev,u8_t * mac)4130 u8_t lm_is_mac_locally_administrated(struct _lm_device_t    *pdev, u8_t * mac)
4131 {
4132     u8_t res = FALSE;
4133     if (mac != NULL)
4134     {
4135         res = (mac[0] != pdev->params.mac_addr[0]) ||
4136               (mac[1] != pdev->params.mac_addr[1]) ||
4137               (mac[2] != pdev->params.mac_addr[2]) ||
4138               (mac[3] != pdev->params.mac_addr[3]) ||
4139               (mac[4] != pdev->params.mac_addr[4]) ||
4140               (mac[5] != pdev->params.mac_addr[5]);
4141     }
4142     return res;
4143 }
4144