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