/*******************************************************************************
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
* Copyright 2014 QLogic Corporation
* The contents of this file are subject to the terms of the
* QLogic End User License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the License at
* See the License for the specific language governing permissions
* and limitations under the License.
*
*
* Module Description:
* This file contains functions having to do with Device info, licensing
* and Bandwidth Allocation
*
******************************************************************************/
#include "lm5710.h"
unsigned long log2_align(unsigned long n);
{
}
{
{
return 0;
}
}
{
{
return 0;
}
}
/*******************************************************************************
* Description:
* reads iscsi_boot info block from shmem
* Return:
* lm_status
******************************************************************************/
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 )
{
// dummy variables so we have convenience way to know the shmem offsets
// This is a pointer so it doesn't load the stack.
// If we delete these lines we won't have shmem_region_t symbols
if ( CHK_NULL( iscsi_info_block_hdr_ptr ) )
{
return LM_STATUS_INVALID_PARAMETER ;
}
{
// only for debugging
if (val == UEFI_BOOT_SIGNATURE)
{
}
else
{
}
}
else
{
// If mcp is detected the shmenm is not initialized and
}
return LM_STATUS_SUCCESS ;
}
)
{
{
//iscsi_info_block_hdr_ptr->signature = val ;
// only for debugging
if (val == UEFI_BOOT_SIGNATURE)
{
*phy_hi = 0;
return LM_STATUS_SUCCESS;
}
}
return LM_STATUS_FAILURE;
}
{
if (!CHIP_IS_E1x(pdev)) {
/* get bars... */
#ifdef VF_INVOLVED
if (rc != LM_STATUS_SUCCESS) {
return rc;
}
#endif
#ifdef __LINUX
lm_set_virt_mode(pdev, DEVICE_TYPE_PF, (pdev->hw_info.sriov_info.total_vfs? VT_BASIC_VF : VT_NONE));
lm_set_virt_mode(pdev, DEVICE_TYPE_PF, (pdev->hw_info.sriov_info.total_vfs? VT_CHANNEL_VF : VT_NONE));
#endif
/* Since registers from 0x000-0x7ff are spilt across functions, each PF will have the same location for the same 4 bits*/
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);
}
return rc;
}
{
{
}
else
{
}
}
/*******************************************************************************
* Description:
*
* Return:
******************************************************************************/
{
/* read the me register to get function number. */
/* Me register: holds the relative-function num + absolute-function num,
* absolute-function-num appears only from E2 and above. Before that these bits
* always contained zero, therefore we can't take as is. */
{
}
else
{
}
DbgMessage(pdev, INFORM , "relative function %d absolute function %d\n", pdev->params.pfunc_rel, pdev->params.pfunc_abs);
return LM_STATUS_SUCCESS;
}
// reads max_payload_size & max_read_req_size from pci config space
{
/* get max payload size and max read size we need it for pxp configuration
in the real chip it should be done by the MCP.*/
if (lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
// bit 5-7
// bit 12-14
return lm_status ;
}
{
/* Get PCI device and vendor id. (need to be read from parent */
{
if (lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
if (val != 0xFFFFFFFF)
{
}
else if (IS_SW_CHANNEL_VIRT_MODE(pdev))
{
}
}
else
{
}
/* Get subsystem and subvendor id. */
if (lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
/* Get IRQ, and interrupt pin. */
if (lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
/* Get cache line size. */
if (lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
/* Get PCI revision id. */
if (lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
/* Get PCI-E speed*/
/* only for PF */
{
if (lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
/* bit 20-25 */
/* bit 16 - 19 */
}
// CQ61532 - Fan Failure test fails when stop the fan for more than 10 seconds and reboot.
// 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
// Hopefully this read will help with other LM drivers
// anyway, we'll fail the bind for that...
{
return LM_STATUS_FAILURE;
}
return lm_status;
}
/**
* This function reads bar offset from PCI configuration
* header.
*
* @param _pdev
* @param bar_num Bar index: BAR_0 or BAR_1 or BAR_2
* @param bar_addr Output value (bar offset).
*
* @return LM_STATUS_SUCCESS if bar offset has been read
* successfully.
*/
{
/* Get BARs addresses. */
switch (bar_num) {
case BAR_0:
break;
case BAR_1:
break;
case BAR_2:
break;
default:
DbgBreakIfAll(1);
return LM_STATUS_INVALID_PARAMETER;
}
if(lm_status != LM_STATUS_SUCCESS) {
return lm_status;
}
if(lm_status != LM_STATUS_SUCCESS) {
return lm_status;
}
return LM_STATUS_SUCCESS;
}
{
switch (bar_num) {
case BAR_0:
break;
case BAR_1:
break;
case BAR_2:
break;
default:
return LM_STATUS_INVALID_PARAMETER;
}
/*extract only bar size*/
if (bar_size == 0)
{
/*bar size disabled*/
return LM_STATUS_FAILURE;
}
else
{
/*bit 1 stand for 64K each bit multiply it by two */
}
return LM_STATUS_SUCCESS;
}
/* init pdev->hw_info with data from pcicfg */
{
u8_t i;
/* Get BARs addresses. */
{
if(lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
{
if(i==0)
{
DbgBreakMsg("BAR 0 must be present\n");
}
}
}
/* TBA: review two intializations done in Teton here (are they needed? are they part of "get_bars_info"):
- Enable PCI bus master....
- Configure byte swap and enable write to the reg_window registers
*/
for (i = 0; i < MAX_NUM_BAR; i++)
{
{
continue;
}
/* get bar i size*/
if ( lm_status != LM_STATUS_SUCCESS )
{
return lm_status;
}
/* Change in BAR1
* The function will map in case of BAR1 only the ETH cid doorbell space to a virtual address.
* (Map from BAR1 base address, to BAR1 base address plus MAX_ETH_CONS* LM_PAGE_SIZE).
*/
if (BAR_1 == i )
{
{ //TODO Revise it
#ifdef VF_INVOLVED
#else
#endif
}
else
{
}
#ifndef VF_INVOLVED
#endif
}
else
{
}
/* Map bar i to system address space. If not mapped already. */
if(lm_is_function_after_flr(pdev) ||
#ifdef VF_INVOLVED
#endif
{
pdev,
i);
{
return LM_STATUS_FAILURE;
}
else
{
DbgMessage(pdev, INFORMi, "mem_base[%d]=%p size=0x%x\n", i, pdev->vars.mapped_bar_addr[i], pdev->hw_info.bar_size[i]);
}
}
}
/* Now that the bars are mapped, we need to enable target read + write and master-enable,
* we can't do this before bars are mapped, but we need to do this before we start any chip
* initializations... */
{
{
mm_read_pci(pdev, pdev->hw_info.pcie_caps_offset + PCIE_DEV_CAPS, &pdev->hw_info.pcie_dev_capabilities);
DbgMessage(pdev, WARN,"Device Capability of PCIe caps is %x\n",pdev->hw_info.pcie_dev_capabilities);
{
{
}
else
{
}
}
else
{
}
}
else
{
}
if (!lm_is_function_after_flr(pdev))
{
if (lm_status == LM_STATUS_SUCCESS)
{
{
}
}
}
}
#endif
if (lm_is_function_after_flr(pdev))
{
{
}
if (tw_e != 0x1)
{
DbgBreakMsg("BAR 0 must be present\n");
return LM_STATUS_FAILURE;
}
}
return LM_STATUS_SUCCESS;
}
{
/* Get the chip revision id and number. */
/* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
/* If OTP process was done on the device, change chip number to 57811 */
if (val & CHIP_OPT_MISC_DO_BIT)
{
{
case CHIP_NUM_57810:
break;
case CHIP_NUM_57810_MF:
break;
default:
DbgBreakIfAll(1);
return LM_STATUS_FAILURE;
}
}
// the chip rev is realy ASIC when it < 5
// when it > 5 odd mean FPGA even EMUL.
if(chip_rev <= CHIP_REV_ASIC_MAX)
{
}
else if(chip_rev & CHIP_REV_SIM_IS_FPGA)
{
}
else
{
}
/* Read silent revision */
if (!CHIP_IS_E1x(pdev))
{
/* Determine whether we are 2 port or 4 port mode */
/* read port4mode_en_ovwr[0];
* b) if 0 read port4mode_en (0 2-port; 1 4-port);
* c) if 1 read port4mode_en_ovwr[1] (0 2-port; 1 4-port);
*/
if ((val & 1) == 0)
{
}
else
{
}
DbgMessage(pdev, WARN, "chip_port_mode %s\n", (pdev->hw_info.chip_port_mode == LM_CHIP_PORT_MODE_4 )? "4_PORT" : "2_PORT");
}
else
{
}
return LM_STATUS_SUCCESS;
}
{
#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)))
#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)))
{
{
}
else
{
}
}
else
{
{
}
{
// mapping CAM; relevant for E2 operating mode only.
// [0] - valid.
// [6:1] - vector number;
// [13:7] - FID (if VF - [13] = 0; [12:7] = VF number; if PF - [13] = 1; [12:9] = 0; [8:7] = PF number);
DbgMessage(pdev, WARN, "addr:0x%x IGU_CAM[%d]=%x\n",IGU_REG_MAPPING_MEMORY + 4*igu_sb_id, igu_sb_id, val);
if (!(val & IGU_REG_MAPPING_MEMORY_VALID))
{
{
}
{
}
else
{
}
continue;
}
else
{
}
if (fid & IGU_FID_ENCODE_IS_PF)
{
{
}
else
{
}
}
else
{
&& (lm_igu_sb->vf_number < (pdev->hw_info.sriov_info.first_vf_in_pf + pdev->hw_info.sriov_info.total_vfs)))
{
}
}
lm_igu_sb->vector_number = (val & IGU_REG_MAPPING_MEMORY_VECTOR_MASK) >> IGU_REG_MAPPING_MEMORY_VECTOR_SHIFT;
{
if (igu_test_vectors)
{
}
else
{
{
/* default status block for default segment + attn segment */
}
else
{
{
}
/* we don't count the default */
}
}
if (recent_vf_id != 0xFF)
{
{
DbgMessage(pdev, WARN, "Consecutiveness of IGU for VF%d is broken. My be it's IGU test mode\n",recent_vf_id);
}
}
}
else if (IS_CHANNEL_VIRT_MODE_MASTER_PFDEV(pdev))
{
if (!(fid & IGU_FID_ENCODE_IS_PF))
{
{
}
/* we don't count the default */
if (recent_vf_id != vf_id)
{
if (recent_vf_id != 0xFF)
{
{
DbgMessage(pdev, WARN, "Consecutiveness of IGU for VF%d is broken. My be it's IGU test mode\n",recent_vf_id);
}
}
}
{
}
else
{
}
}
else
{
if (recent_vf_id != 0xFF)
{
{
DbgMessage(pdev, WARN, "Consecutiveness of IGU for VF%d is broken. My be it's IGU test mode\n",recent_vf_id);
}
}
}
{
/* We've already found our base... but now we don't match... these are now igu-test-vectors */
if (!igu_test_vectors)
{
}
}
}
else
{
/* No Match - belongs to someone else, check if breaks consecutiveness, if so, break at this point
* driver doesn't support non-consecutive vectors (EXCEPT Def sb...) */
{
/* We've already found our base... but now we don't match... these are now igu-test-vectors */
if (!igu_test_vectors) {
}
}
}
}
// TODO check cam is valid...
#ifndef _VBD_
#endif
/* E2 TODO: if we don't want to separate u/c/ producers in IGU, this line needs to
* be removed, and igu_u_offset needs to be set to 'zero'
blk_info->igu_info.igu_u_sb_offset = blk_info->igu_info.igu_sb_cnt / 2;*/
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",
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,
/* CQ61438 - do not show this error message in case of mf mode changed to SF and func >= 2*/
{
{
}
{
}
}
In case we are in INTA mode, we limit the igu count to 31 as we can't handle more than that */
if (pdev->params.b_inta_mode_prvided_by_os && (blk_info->igu_info.igu_sb_cnt > IGU_MAX_INTA_SB_CNT ))
{
}
}
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);
}
/*
* Assumptions:
* - the following are initialized before call to this function:
* chip-id, func-rel,
*/
{
if (CHIP_IS_E1x(pdev))
{
/* The next part is tricky... and has to do with an emulation work-around for handling interrupts, in which
* we want to read without mask - always... so we take care of it here, instead of changing different ums to
* call approriate function */
if (CHIP_REV_IS_EMUL(pdev))
{
}
else
{
}
}
else
{
/* If we have more than 32 status blocks we'll need to read from IGU_REG_SISR_MDPC_WMASK_UPPER */
if (REG_RD(PFDEV(pdev), IGU_REG_BLOCK_CONFIGURATION) & IGU_BLOCK_CONFIGURATION_REG_BACKWARD_COMP_EN)
{
}
else
{
}
/* read CAM to get igu info (must be called after we know if we're in backward compatible mode or not )*/
{
{
DbgBreakMsg("VF Can't work in GRC Access mode!\n");
return LM_STATUS_FAILURE;
}
/* [18:12] - FID (if VF - [18] = 0; [17:12] = VF number; if PF - [18] = 1; [17:14] = 0; [13:12] = PF number) */
blk_info->simd_addr_womask = IGU_REG_COMMAND_REG_32LSB_DATA; /* this is where data will be after writing ctrol reg... */
/* The next part is tricky... and has to do with an emulation work-around for handling interrupts, in which
* we want to read without mask - always... so we take care of it here, instead of changing different ums to
* call approriate function */
if (CHIP_REV_IS_EMUL(pdev))
{
}
else
{
}
blk_info->simd_addr_wmask = IGU_REG_COMMAND_REG_32LSB_DATA; /* this is where data will be after writing ctrol reg... */
}
else
{
/* The next part is tricky... and has to do with an emulation work-around for handling interrupts, in which
* we want to read without mask - always... so we take care of it here, instead of changing different ums to
* call approriate function */
if (CHIP_REV_IS_EMUL(pdev))
{
}
else
{
}
}
}
return LM_STATUS_SUCCESS;
}
{
return LM_STATUS_SUCCESS;
}
/* for ediag + lediat we don't really care about licensing!... */
#define MAX_CONNECTIONS_FCOE 0
#else
#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)
but no more 16K to limit ilt client page size by 64KB*/
#define MAX_CONNECTIONS_TOE (min(8192,MAX_CONNECTIONS - MAX_CONNECTIONS_ISCSI - MAX_CONNECTIONS_RDMA - MAX_CONNECTIONS_FCOE - MAX_ETH_CONS - MAX_CONNECTIONS_VF))
#endif
#define MAX_CONNECTIONS_TOE_NO_LICENSE 0
#define MAX_CONNECTIONS_ISCSI_NO_LICENSE 0
#define MAX_CONNECTIONS_RDMA_NO_LICENSE 0
#define MAX_CONNECTIONS_FCOE_NO_LICENSE 0
{
if (is_high)
{
val &=0xFFFF0000;
if(val)
{
}
val >>= 16;
}
else
{
val &= 0xffff;
if(val)
{
}
}
return val;
}
{
return val;
}
/* No special MCP handling for a specific E1H configuration */
/* WARNING: Do Not Change these defines!!! They are used in an external tcl script that assumes their values!!! */
{
/* Even though only one port actually does the initialization, ALL functions need to know the maximum number of connections
* because that's how they know what the page-size-is, and based on that do per-function initializations as well. */
/* get values for relevant ports. */
{
{
// check that licensing is enabled
if(GET_FLAGS(val, SHR_MEM_VALIDITY_LIC_MANUF_KEY_IN_EFFECT | SHR_MEM_VALIDITY_LIC_UPGRADE_KEY_IN_EFFECT))
{
// align to 32 bit
/* RDMA */
/* ISCSI */
/* FCOE */
{
max_fcoe_cons[port] = 0;
}
else
{
}
}
else
{
// In case MCP is enabled and there is no licence => there should be no offload connection.
}
if (CHIP_IS_E1x(pdev))
{
}
else
{
}
/* get the bar size... unless it's current port and then we have it. otherwise, read from shmem W.C which
* is what the other ports asked for, they could have gotten less, but we're looking into the worst case. */
{
}
else
{
if (val != 0)
{
/* bit 1 stand for 64K each bit multiply it by two */
}
}
}
else
{
// MCP_WA
if (val == NO_MCP_WA_VALID_LIC_MAGIC)
{
/* FCOE */
// For backward compatibility, same value if it will be required we can add NO_MCP_WA_FCOE_LIC
// Fcoe licencing isn't supported.
/*
LM_SHMEM_READ(pdev, NO_MCP_WA_FCOE_LIC+4*port, &val);
max_fcoe_cons[port] = val;
*/
}
else
{
#ifdef VF_INVOLVED
#else
#endif
// Need to review this value seems like we take in this case the max value
}
if (CHIP_IS_E1x(pdev))
{
}
else
{
}
/* For MCP - WA, we always assume the same bar size for all ports: makes life simpler... */
}
/* so after all this - what is the maximum number of connections supported for this port? */
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]);
/* And after all this... in lediag / ediag... we assume a maximum of 1024 connections */
#endif
{
}
}
/* Now, port specific... */
/* 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
* numbers relatively... can't touch MAX_ETH_CONS... */
{
return LM_STATUS_INVALID_PARAMETER;
}
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])
{
/* we first try giving iscsi + rdma what they asked for... */
if ((max_iscsi_cons[port] + max_rdma_cons[port] + max_fcoe_cons[port] + max_eth_cons[port]) > max_supported_cons[port])
{
u32_t s = max_iscsi_cons[port] + max_rdma_cons[port] + max_toe_cons[port] + max_fcoe_cons[port]; /* eth out of the game... */
u32_t t = max_supported_cons[port] - pdev->params.max_eth_including_vfs_conns; /* what we want to reach... */
/* relatively decrease all... (x+y+z=s, actual = t: xt/s+yt/s+zt/s = t) */
max_iscsi_cons[port] *=t;
max_iscsi_cons[port] /=s;
max_rdma_cons[port] *=t;
max_rdma_cons[port] /=s;
max_toe_cons[port] *=t;
max_toe_cons[port] /=s;
max_fcoe_cons[port] *=t;
max_fcoe_cons[port] /=s;
}
else
{
/* just give toe what's left... */
max_toe_cons[port] = max_supported_cons[port] - (max_iscsi_cons[port] + max_rdma_cons[port] + max_fcoe_cons[port] + max_eth_cons[port]);
}
}
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]))
{
return LM_STATUS_INVALID_PARAMETER;
}
/* Now lets save our port-specific variables. By this stage we have the maximum supported connections for our port. */
/* RDMA */
/* ISCSI */
/* FCOE */
{
/* this would mean an error in the calculations above. */
return LM_STATUS_INVALID_PARAMETER;
}
return LM_STATUS_SUCCESS;
}
{
u8_t i = 0;
u8_t j = 0;
/* hard coded offsets in vnic_cfg.tcl. if assertion here fails,
* need to fix vnic_cfg.tcl script as well. */
// ASSERT_STATIC(OFFSETOF(shmem_region_t,mf_cfg) == 0x7e4);
//ASSERT_STATIC(MCP_CLP_MB_NO_CLP == 0x80000000); not yet defined
/* trace mf cfg parameters */
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",
DbgMessage(pdev, INFORMi, "\t mac addr (overiding main and iscsi): %02x %02x %02x %02x %02x %02x\n",
/* verify that function is not hidden */
{
goto _end;
}
{
//DbgBreakIf(1);
goto _end;
}
/* Sanity checks on outer-vlan for switch_dependent_mode... */
{
/* enumerated vnic id > 0 must have valid ovlan if we're in switch-dependet mode */
{
DbgMessage(pdev, WARNi, "invalid mf mode configuration: VNICID=%d, Function is enumerated, ovlan (%d) is invalid\n",
#ifdef EDIAG
// Allow OVLAN 0xFFFF in ediag UFP mode
{
}
#else
#endif
goto _end;
}
/* additional sanity checks */
{
#ifdef EDIAG
// Allow OVLAN 0xFFFF in ediag UFP mode
{
}
#else
#endif
goto _end;
}
/* verify all functions are either mf mode or sf mode:
* if we set mode to mf, make sure that all non hidden functions have valid ovlan
* if we set mode to sf, make sure that all non hidden functions have invalid ovlan */
{
{
#ifdef EDIAG
// Allow OVLAN 0xFFFF in eDiag UFP mode
{
}
#else
#endif
goto _end;
}
}
/* verify different ovlan between funcs on same port */
{
/* iterate from the next function in the port till max func */
{
{
DbgBreakIf(1);
goto _end;
}
}
}
// Check if DCC is active (Debugging only)
LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, port_mf_config[PATH_ID(pdev)][PORT_ID(pdev)].dynamic_cfg),&dynamic_cfg );
{
}
else
{
}
} // MULTI_FUNCTION_SD
_end:
return lm_status;
}
{
u8_t i = 0;
if( !IS_MF_MODE_CAPABLE(pdev) )
{
DbgBreakIf(1) ;
return;
}
{
vnic++;
}
}
/**lm_get_vnics_per_port
* Get the value of vnics_per_port according to the MF mode and
* port mode.
*
* Note: This function assumes that multi_vnics_mode and
* chip_port_mode are initialized in hw_info.
*
* @param pdev
*
* @return u8_t the value of vnics_per_port for this pdev's port
* mode and MF mode. This value does not consider hidden
* PFs.
*/
{
{
return LM_PFS_PER_PORT(pdev);
}
else
{
return 1;
}
}
/* Get shmem multi function config info for switch dependent mode */
{
/* get ovlan if we're in switch-dependent mode... */
{
/* Unexpected at this time */
DbgMessage(pdev, FATAL, "Invalid mf mode configuration: VNICID=%d, Function is enumerated, ovlan (%d) is invalid\n",
#ifdef EDIAG
// Allow OVLAN 0xFFFF in ediag UFP mode
{
return LM_STATUS_FAILURE;
}
#else
return LM_STATUS_FAILURE;
#endif
}
/* Get capabilities */
{
}
{
}
else
{
}
return LM_STATUS_SUCCESS;
}
/* Get shmem multi function config info for switch dependent mode */
{
return lm_status;
}
/* Get shmem multi function config info for switch dependent mode */
{
return lm_status;
}
static void _copy_mac_upper_lower_to_arr(IN u32_t mac_upper, IN u32_t mac_lower, OUT u8_t* mac_addr)
{
if(mac_addr)
{
}
}
{
/* 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
* we'll leave the same mac as for L2
*/
}
static u32_t
{
{
{
}
{
}
{
}
}
return proto_support_flags;
}
/* Get shmem multi function config info for switch independent mode */
{
/* No outer-vlan... we're in switch-independent mode, so if the mac is valid - assume multi-function */
return LM_STATUS_SUCCESS;
}
{
LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[ABS_FUNC_ID(pdev)].afex_config), &niv_config);
mf_info->ext_id = (u16_t)(GET_FLAGS(e1hov_tag, FUNC_MF_CFG_E1HOV_TAG_MASK)>>FUNC_MF_CFG_E1HOV_TAG_SHIFT);
mf_info->default_vlan = (u16_t)(GET_FLAGS(e1hov_tag, FUNC_MF_CFG_AFEX_VLAN_MASK)>>FUNC_MF_CFG_AFEX_VLAN_SHIFT);
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);
mf_info->niv_default_cos = (u8_t)(GET_FLAGS(func_config, FUNC_MF_CFG_TRANSMIT_PRIORITY_MASK)>>FUNC_MF_CFG_TRANSMIT_PRIORITY_SHIFT);
mf_info->afex_vlan_mode = GET_FLAGS(niv_config, FUNC_MF_CFG_AFEX_VLAN_MODE_MASK)>>FUNC_MF_CFG_AFEX_VLAN_MODE_SHIFT;
mf_info->niv_mba_enabled = GET_FLAGS(niv_config, FUNC_MF_CFG_AFEX_MBA_ENABLED_MASK)>>FUNC_MF_CFG_AFEX_MBA_ENABLED_SHIFT;
return LM_STATUS_SUCCESS;
}
{
u8_t i;
/* set defaults: */
mf_info->multi_vnics_mode = 0;
{
}
return LM_STATUS_SUCCESS;
}
{
if (CHIP_IS_E1(pdev))
{
min_shmem_addr = 0xa0000;
max_shmem_addr = 0xb0000;
}
else if (CHIP_IS_E1H(pdev))
{
min_shmem_addr = 0xa0000;
max_shmem_addr = 0xc0000;
}
else if (CHIP_IS_E2E3(pdev))
{
min_shmem_addr = 0x3a0000;
max_shmem_addr = 0x3c8000;
}
else
{
DbgBreakMsg("Unknown chip version");
}
{
/* Invalid shmem base address return '0' */
val = 0;
}
return val;
}
/**
* @Description
* This function is called when MCP is not detected. It
* initializes lmdevice parameters that are required for
* functional running with default values or values read
* from vnic_cfg.tcl script.
*
* @param pdev
*
* @return lm_status_t
*/
{
#ifndef _VBD_CMD_
#endif // _VBD_CMD_
/* should have a magic number written if configuration was set otherwise, use default above */
if (val == NO_MCP_WA_CFG_SET_MAGIC)
{
if (mf_info->multi_vnics_mode)
{
/* 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 */
{
}
/* For simplicity, we leave vnics_per_port to be 2, for resource splitting issues... */
if (mf_info->path_has_ovlan)
{
{
}
else
{
}
}
/* If we're multi-vnic, we'll set a default mf_mode of switch-dependent, this could be overriden
* later on by registry */
}
if (lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
}
/* sanity checks on vnic params */
if (mf_info->multi_vnics_mode)
{
{
}
}
if ((mf_info->vnics_per_port - 1 < VNIC_ID(pdev)) || ( !mf_info->multi_vnics_mode && (VNIC_ID(pdev) > 0)))
{
DbgMessage(pdev, FATAL, "Invalid vnics_per_port (%d) configured for Func %d. Can't load the function.\n",
}
return lm_status;
}
{
u8_t i = 0;
/* Get the hw config words. */
pdev->params.link.hw_led_mode = ((pdev->hw_info.nvm_hw_config & SHARED_HW_CFG_LED_MODE_MASK) >> SHARED_HW_CFG_LED_MODE_SHIFT);
//board_sn;
for (i = 0 ; i < 16 ; i++ )
{
}
/* Get the override preemphasis flag */
{
SET_FLAGS( pdev->params.link.feature_config_flags, ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED);
}
else
{
RESET_FLAGS(pdev->params.link.feature_config_flags,ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED);
}
#ifdef EDIAG
/* Diag doesn't support remote fault detection */
/* Only Diag supports IEEE PHY testing */
#endif
return LM_STATUS_SUCCESS;
}
{
offset = pdev->hw_info.shmem_base + OFFSETOF(shmem_region_t, func_mb) + E1H_FUNC_MAX * sizeof(struct drv_func_mb);
{
{
{
}
}
}
return offset;
}
{
/* mba features*/
&val);
/* mba_vlan_cfg */
&val);
// port_feature_config bits
&val);
#ifndef DOS
/* AutogrEEEn settings */
if(val & PORT_FEAT_CFG_AUTOGREEEN_ENABLED) {
} else {
}
#endif
/* clc params*/
LM_SHMEM_READ(pdev,OFFSETOF(shmem_region_t,dev_info.port_hw_config[port].speed_capability_mask),&val);
LM_SHMEM_READ(pdev,OFFSETOF(shmem_region_t,dev_info.port_hw_config[port].speed_capability_mask2),&val);
/* Get lane swap*/
/*link config */
/* set the initial value to the link params */
/* save the initial value if we'll want to restore it later */
/* check if 10g KR is blocked on this session */
/* If the force KR enabler is on, 10G/20G should have been enabled in the
* nvram as well. If 10G/20G capbility is not set, it means that the MFW
* disabled it and we should set the no_10g_kr flag */
( FALSE == ( pdev->params.link.speed_cap_mask[0] & (PORT_HW_CFG_SPEED_CAPABILITY_D0_10G | PORT_HW_CFG_SPEED_CAPABILITY_D0_20G))) )
{
}
/* read EEE mode from shmem (original source is NVRAM) */
LM_SHMEM_READ(pdev,OFFSETOF(shmem_region_t,dev_info.port_feature_config[port].eee_power_mode),&val);
if ((pdev->params.link.eee_mode & PORT_FEAT_CFG_EEE_POWER_MODE_MASK) != PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED)
{
}
return LM_STATUS_SUCCESS;
}
/* Check if other path is in multi_function_mode */
{
{
}
{
/* 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 */
{
}
}
}
/**
* @Description
* Initializes mf mode and data, checks that mf info is valid
* by checking that MAC address must be legal (check only upper
* bytes) for Switch-Independent mode;
* OVLAN must be legal for Switch-Dependent mode
*
* @param pdev
*
* @return lm_status_t
*/
{
/* Set some mf_info defaults */
/* Get the multi-function-mode value (switch dependent / independent / single-function ) */
switch (val)
{
/* check for legal mac (upper bytes)*/
{
}
else
{
}
break;
/* get OV configuration */
if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT)
{
}
else
{
}
break;
/* We're not in multi-function mode - return with vnics_per_port=1 & multi_vnics_mode = FALSE*/
return LM_STATUS_SUCCESS;
/* mark mf mode as NIV if MCP version includes NPAR-SD support
and the MAC address is valid.
*/
{
}
else
{
}
break;
break;
break;
/* Get extended mf mode value */
switch (val2)
{
break;
default:
DbgBreakMsg(" Unknown extended mf mode\n");
return LM_STATUS_FAILURE;
}
break;
default:
DbgBreakMsg(" Unknown mf mode\n");
return LM_STATUS_FAILURE;
}
/* Set path mf_mode (which could be different than function mf_mode) */
/* Invalid Multi function configuration: */
{
{
return LM_STATUS_FAILURE;
}
return LM_STATUS_SUCCESS;
}
/* Get the multi-function configuration */
{
case MULTI_FUNCTION_SD:
{
{
case SD_REGULAR_MODE:
break;
case SD_UFP_MODE:
break;
case SD_BD_MODE:
break;
default:
DbgBreak();
}
if(status != LM_STATUS_SUCCESS)
return status;
}
break;
case MULTI_FUNCTION_SI:
{
}
break;
case MULTI_FUNCTION_AFEX:
{
}
break;
default:
{
return LM_STATUS_FAILURE;
}
}
return lm_check_valid_mf_cfg(pdev);
}
{
/* create default wwns from fcoe mac adress */
}
{
{
return LM_STATUS_FAILURE;
}
/* Get the permanent L2 MAC address. */
/* Mac validity is assumed since we already checked it to determine mf_mode. And we assume mf_mode
* is configured correctly when we enter this function. */
/* Set iSCSI / FCOE Mac addresses */
{
case MULTI_FUNCTION_SD:
{
// in E1x the ext mac doesn't exists and will cause MCP parity error CQ67469
{
/* Set all iscsi and fcoe mac addresses the same as network. */
break;
}
}
case MULTI_FUNCTION_SI:
case MULTI_FUNCTION_AFEX:
break;
}
return LM_STATUS_SUCCESS;
}
{
/* Get iSCSI MAC address. */
/* Get FCoE MAC addresses. */
return LM_STATUS_SUCCESS;
}
/* Gets the sriov info from shmem of ALL functions and marks if configuration is assymetric */
{
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));
if (CHIP_IS_E1x(pdev))
{
return;
}
{
if (0 == val)
{
sriov_disabled = 1;
}
else
{
sriov_enabled = 1;
}
{
}
}
/* check if assymteric configuration...basically we initialize both params to 0xff, so the only way they can both be
* the same is if one of the ports was enabled and one was disabled... */
if (sriov_disabled == sriov_enabled)
{
}
else
{
}
}
{
ASSERT_STATIC((FIELD_SIZE(struct mf_cfg, func_mf_config) / FIELD_SIZE(struct mf_cfg, func_mf_config[0])) == E2_FUNC_MAX*2);
if (CHIP_IS_E1x(pdev))
{
return;
}
{
if (0 == val)
{
sriov_disabled = 1;
}
else
{
sriov_enabled = 1;
}
if (abs_func_idx == abs_func)
{
}
}
/* check if assymteric configuration...basically we initialize both params to 0xff, so the only way they can both be
* the same is if one of the ports was enabled and one was disabled... */
if (sriov_disabled == sriov_enabled)
{
}
else
{
}
}
{
{
}
else
{
}
return lm_status;
}
{
{
return;
}
{
}
else
{
}
}
{
// cq57766
// if this static assert fails consider adding the new mode to the if
// and read the l2_fw_flow_ctrl from the shmem in the new mode also
// l2_fw_flow_ctrl is read from the shmem in multi-function mode in E2 and above.
// In all other cases this parameter is read from the registry.
// We read this parameter from the registry in E1.5 multi-function since 57711 boot code does not have the struct func_ext_cfg
(!CHIP_IS_E1x(pdev)))
{
LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_ext_config[ABS_FUNC_ID(pdev)].func_cfg), &func_ext_cfg);
{
}
else
{
}
}
}
/**
* @Description
* This function is responsible for reading all the data
* that the driver needs before loading from the shmem.
*
* @param pdev
*
* @return lm_status_t
*/
{
if (!val)
{
return lm_get_shmem_info_no_mcp_bypass(pdev);
}
pdev->hw_info.shmem_base2 = REG_RD(pdev, PATH_ID(pdev) ? MISC_REG_GENERIC_CR_1 : MISC_REG_GENERIC_CR_0);
if(LM_STATUS_SUCCESS != lm_status )
{
return LM_STATUS_SUCCESS;
}
/* bc rev */
if (lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
if (lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
#ifdef _LICENSE_H
if (lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
#endif
/* get mf config parameters */
{
if (lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
}
{
return LM_STATUS_FAILURE;
}
return lm_status;
}
{
{
// Only if LFA is supported in MFW
{
}
}
///TODO remove - the initialization in lm_mcp_cmd_init should be enough, but BC versions are still in flux.
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.
{
}
if (CHIP_REV_IS_SLOW(pdev))
{
{
}
else if (val & 0x4)
{
// force to work with emac
if (CHIP_IS_E3(pdev))
{
}
else
{
}
}
else if (val & 0x8)
{
if (CHIP_IS_E3(pdev))
{
}
else
{
}
}
/* Disable EMAC for E3 and above */
if (val & 2)
{
}
}
}
/** lm_init_cam_params
*
* cam mapping is dynamic, we only set sizes...
*
*/
{
/* FIXME: remove once constants are in hsi file */
#define LM_CAM_SIZE_EMUL (5) /*5 per vnic also in single function mode (real cam size on emulation is 20 per port) */
if (CHIP_IS_E1(pdev))
{
/* init unicast table entires */
/* init multicast table entires */
DbgMessage(pdev, INFORMi, "uc_table_size[ndis]=%d, uc_table_size[ndis]=%d, mc_table_size[ndis]=%d\n",
}
else if (CHIP_IS_E1H(pdev))
{
/* init unicast table entires */
/* init multicast table entires */
DbgMessage(pdev, INFORMi, "uc_table_size[ndis]=%d, uc_table_size[ndis]=%d, mc_table_size[ndis]=%d\n",
}
else if (CHIP_IS_E2E3(pdev))
{
if (num_funcs > 1)
{
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;
}
else
{
}
/* init unicast table entires */
/* init multicast table entires */
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",
}
else
{
DbgBreakIfAll("New Chip?? initialize cam params!\n");
}
/* override CAM parameters for chips later than E1 */
{
pdev->params.base_offset_in_cam_table = ((num_ports == 2)? FUNC_ID(pdev) : VNIC_ID(pdev)) * LM_CAM_SIZE(pdev);
}
else if (IS_CHANNEL_VFDEV(pdev))
{
pdev->params.mc_table_size[LM_CLI_IDX_NDIS] = 0; /* Will be filled later on acquire response (HW_CHANNEL)*/
}
}
/*
* \brief Initialize pdev->params members
*
* This function initializes the various pdev->params members, depending
* on chip technology/implementation: fpga, emul or asic (default).
*
* The function may also be used to validate these parameters.
*
* \param[in,out] pdev
* \param[in] validate flag to indicate desired operation.
*
*/
{
typedef struct _param_entry_t
{
/* Ideally, we want to save the address of the parameter here.
* However, some compiler will not allow us to dynamically
* initialize the pointer to a parameter in the table below.
* As an alternative, we will save the offset to the parameter
* from pdev device structure. */
/* Parameter default value. */
/* Limit checking is diabled if min and max are zeros. */
{
/* asic fpga emul
offset default default default min max */
// { _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 },
/* The maximum page count is chosen to prevent us from having
* more than 32767 pending entries at any one time. */
/* NirV: still not supported in ediag, being set in the windows mm */
// { _OFFSET(l2_rx_desc_cnt[LM_CLI_IDX_ISCSI]), 200, 200, 200, 0, 32767 },
//
// /* The maximum page count is chosen to prevent us from having
// * more than 32767 pending entries at any one time. */
// { _OFFSET(l2_tx_bd_page_cnt[LM_CLI_IDX_ISCSI]), 2, 2, 2, 1, 127 },
// { _OFFSET(l2_tx_coal_buf_cnt[LM_CLI_IDX_ISCSI]), 0, 0, 0, 0, 20 },
// { _OFFSET(l2_rx_bd_page_cnt[LM_CLI_IDX_ISCSI]), 1, 1, 1, 1, 127 },
{ _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
{ _OFFSET(interrupt_mode), LM_INT_MODE_INTA, LM_INT_MODE_INTA, LM_INT_MODE_INTA, LM_INT_MODE_INTA, LM_INT_MODE_MIMD},
{ _OFFSET(igu_access_mode), INTR_BLK_ACCESS_IGUMEM, INTR_BLK_ACCESS_IGUMEM, INTR_BLK_ACCESS_IGUMEM, INTR_BLK_ACCESS_GRC, INTR_BLK_ACCESS_IGUMEM},
{ _OFFSET(selective_autoneg), 0, 0, 0, 0, 0 },
{ _OFFSET(autogreeen), LM_AUTOGREEEN_NVRAM, LM_AUTOGREEEN_NVRAM, LM_AUTOGREEEN_NVRAM, LM_AUTOGREEEN_DISABLED, LM_AUTOGREEEN_NVRAM },
// TODO add correct values here
#ifdef VF_INVOLVED
#else
#endif
{ _OFFSET(context_line_size), LM_CONTEXT_SIZE, LM_CONTEXT_SIZE, LM_CONTEXT_SIZE, 0, LM_CONTEXT_SIZE },
// network type and max cwnd
{ _OFFSET(network_type), LM_NETOWRK_TYPE_WAN, LM_NETOWRK_TYPE_WAN, LM_NETOWRK_TYPE_WAN,LM_NETOWRK_TYPE_LAN, LM_NETOWRK_TYPE_WAN },
// cid allocation mode
{ _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},
// interrupt coalesing configuration
{ _OFFSET(int_coalesing_mode), LM_INT_COAL_PERIODIC_SYNC, LM_INT_COAL_NONE, LM_INT_COAL_NONE, 1, LM_INT_COAL_NUM_MODES },
// VF interrupt coalesing configuration
{ _OFFSET(hc_timeout0[SM_RX_ID][0]), 12, 12, 12, 1, 0xff }, /* (20K int/sec assuming no more btr) */
{ _OFFSET(hc_timeout2[SM_RX_ID][1]), 120, 120, 120, 1, 0xff }, /* (2K int/sec assuming no more btr) */
{ _OFFSET(hc_timeout3[SM_RX_ID][1]), 240, 240, 240, 1, 0xff }, /* (1K int/sec assuming no more btr) */
{ _OFFSET(hc_timeout2[SM_RX_ID][2]), 120, 120, 120, 1, 0xff }, /* (2K int/sec assuming no more btr) */
{ _OFFSET(hc_timeout3[SM_RX_ID][2]), 240, 240, 240, 1, 0xff }, /* (1K int/sec assuming no more btr) */
{ _OFFSET(hc_timeout2[SM_RX_ID][3]), 120, 120, 120, 1, 0xff }, /* (2K int/sec assuming no more btr) */
{ _OFFSET(hc_timeout3[SM_RX_ID][3]), 240, 240, 240, 1, 0xff }, /* (1K int/sec assuming no more btr) */
{ _OFFSET(hc_timeout0[SM_TX_ID][0]), 12, 12, 12, 1, 0xff }, /* (20K int/sec assuming no more btr) */
{ _OFFSET(hc_timeout2[SM_TX_ID][1]), 120, 120, 120, 1, 0xff }, /* (2K int/sec assuming no more btr) */
{ _OFFSET(hc_timeout3[SM_TX_ID][1]), 240, 240, 240, 1, 0xff }, /* (1K int/sec assuming no more btr) */
{ _OFFSET(hc_timeout1[SM_TX_ID][2]), 12, 12, 12, 1, 0xff }, /* (20K int/sec assuming no more btr) */
{ _OFFSET(hc_timeout3[SM_TX_ID][2]), 64, 64, 64, 1, 0xff }, /* (3.75K int/sec assuming no more btr) */
{ _OFFSET(hc_timeout2[SM_TX_ID][3]), 120, 120, 120, 1, 0xff }, /* (2K int/sec assuming no more btr) */
{ _OFFSET(hc_timeout3[SM_TX_ID][3]), 240, 240, 240, 1, 0xff }, /* (1K int/sec assuming no more btr) */
// { _OFFSET(l4_hc_scaling_factor), 12, 12, 12, 0, 16 },
// l4 params
{ _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)) */
//congestion managment parameters
// safc
// fairness
// rate shaping
// Demo will be removed later
// iscsi
// fcoe
#if 0
#else
#endif
{ _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},
{ _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},
{ 0, 0, 0, 0, 0, 0}
}; // param_list
u8_t i = 0;
if (!validate)
{
/* Initialize the default parameters. */
param = param_list;
{
if(CHIP_REV_IS_FPGA(pdev))
{
}
else if(CHIP_REV_IS_EMUL(pdev))
{
}
else
{
}
param++;
}
{
/* base non-default status block idx - 0 in E1. 0, 4, 8 or 12 in E1H */
if (CHIP_IS_E1x(pdev))
{
pdev->params.max_pf_sb_cnt = pdev->params.fw_sb_cnt = HC_SB_MAX_SB_E1X / 2 / pdev->params.vnics_per_port;
if (CHIP_IS_E1(pdev)) {
} else {
pdev->params.fw_client_cnt = pdev->params.max_pf_fw_client_cnt = ETH_MAX_RX_CLIENTS_E1H / pdev->params.vnics_per_port;
}
}
else
{
#ifdef _VBD_
// pdev->params.sb_cnt = min(LM_IGU_SB_CNT(pdev), MAX_RSS_CHAINS);
#endif
}
// Asymmetric resource division
#ifndef LM_NUM_DSBS
#endif
{
pdev->params.fw_aux_qzone_cnt = (ETH_MAX_RX_CLIENTS_E2 - PXP_REG_HST_ZONE_PERMISSION_TABLE_SIZE) / pdev->params.vnics_per_port / 2;
port_base_aux_qzone = PORT_ID(pdev)* ((ETH_MAX_RX_CLIENTS_E2 - PXP_REG_HST_ZONE_PERMISSION_TABLE_SIZE)/PORT_MAX);
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;
pdev->params.base_fw_client_id = pdev->params.base_fw_ndsb + FUNC_ID(pdev) * MAX_NON_RSS_FW_CLIENTS;
}
else
{
pdev->params.fw_aux_qzone_cnt = (ETH_MAX_RX_CLIENTS_E2 - PXP_REG_HST_ZONE_PERMISSION_TABLE_SIZE) / pdev->params.vnics_per_port;
pdev->params.aux_fw_qzone_id = PXP_REG_HST_ZONE_PERMISSION_TABLE_SIZE + VNIC_ID(pdev) * pdev->params.fw_aux_qzone_cnt;
pdev->params.base_fw_client_id = pdev->params.base_fw_ndsb + VNIC_ID(pdev) * MAX_NON_RSS_FW_CLIENTS;
}
#ifdef VF_INVOLVED
{
}
else
{
}
#else
#endif
}
pdev->params.base_fw_ndsb, pdev->params.sb_cnt, pdev->params.max_pf_sb_cnt, pdev->params.fw_sb_cnt);
// pdev->params.base_fw_client_id = VNIC_ID(pdev) * pdev->params.fw_client_cnt;
if (CHIP_IS_E2E3(pdev)) {
{
}
DbgMessage(pdev, WARN, "%d base FW Q zone IDs from %d\n", pdev->params.fw_base_qzone_cnt, base_fw_qzone_id);
DbgMessage(pdev, WARN, "%d aux FW Q zone IDs from %d\n", pdev->params.fw_aux_qzone_cnt, pdev->params.aux_fw_qzone_id);
}
// pdev->params.base_fw_client_id = VNIC_ID(pdev) * (pdev->params.sb_cnt + MAX_NON_RSS_FW_CLIENTS);
/* For now, base_fw_qzone_id == base_fw_client_id, but this doesn't have to be the case... */
/* qzone-id is relevant only for E2 and therefore it is ok that we use a */
/* Todo - change once E2 client is added. */
// pdev->params.base_fw_qzone_id = pdev->params.base_fw_client_id + ETH_MAX_RX_CLIENTS_E1H*PORT_ID(pdev);
/* E2 TODO: read how many sb each pf has...?? */
} else if (IS_CHANNEL_VFDEV(pdev)) {
} else {
}
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));
{
}
#ifndef EDIAG
{
DbgBreakMsg("Zero isn't a valid value for pdev->params.max_rss_chains ");
return LM_STATUS_FAILURE;
}
#endif
/* set the clients cids that will be used by the driver */
// pdev->params.map_client_to_cid[LM_CLI_IDX_RDMA] = ++i;
// FCoE is not supported in E1 and we have only 18 clients in E1
// so we OOO client gets 'priority' over FCoE
DbgBreakIf(pdev->params.map_client_to_cid[LM_CLI_IDX_OOO] > pdev->params.map_client_to_cid[LM_CLI_IDX_FCOE]);
/* L4 RSS */
/* set l4_rss base chain index to be the first one after l2 */
if (CHIP_IS_E1x(pdev))
{
}
else
{
}
/* master-pfdev needs to keep resources for its vfs, resource allocation is done first between
* pfs and then each pf leaves itself 1 sb_cnt for enabling vfs. */
if((CHIP_REV_IS_SLOW(pdev)
#ifdef DUMMY_MAC_FOR_VF
#endif
)
&&
{
pdev->params.mac_addr[4] = pdev->hw_info.mac_addr[4] = 0x70 + (IS_PFDEV(pdev) ? 0 : (1 + 64*PATH_ID(pdev) + ABS_VFID(pdev)));
if (CHIP_IS_E1x(pdev))
{
}
else
{
pdev->params.mac_addr[5] = pdev->hw_info.mac_addr[5] = 0x9a + PATH_ID(pdev)*8 + PORT_ID(pdev)*4 + VNIC_ID(pdev)*2;
}
}
else
{
}
if(CHIP_REV_IS_EMUL(pdev))
{
//pdev->params.test_mode |= TEST_MODE_NO_MCP;
}
else
{
}
{
}
switch (flow_control)
{
break;
break;
break;
break;
break;
default:
break;
}
/*
* We don't know (yet...) if the PHY supportes EEE - so we cannot set params
* to reflect this info.
*/
/* L2 FW Flow control */
// cq57766
// if this static assert fails consider adding the new mode to the if
// and read the l2_fw_flow_ctrl from the shmem in the new mode also
(CHIP_IS_E1x(pdev)))
{
// l2_fw_flow_ctrl is read from the shmem in multi-function mode in E2 and above.
// In all other cases this parameter is read from the registry.
// We read this parameter from the registry in E1.5 multi-function since 57711 boot code does not have the struct func_ext_cfg
}
{
}
}
else
{
/* Make sure the parameter values are within range. */
param = param_list;
{
{
{
if(CHIP_REV_IS_FPGA(pdev))
{
}
else if(CHIP_REV_IS_EMUL(pdev))
{
}
else
{
}
}
}
param++;
}
/* calculate context_line_size context_waste_size */
// TODO calculate number of context lines in alocation page.
//csize = max(sizeof(struct rdma_context),csize);
/* Check for a valid mac address. */
{
}
if (CHIP_IS_E1(pdev))
{
{
}
}
}
/* init l2 client conn param with default mtu values */
{
{
// in case lm_cli_idx is above boundries
// it means that is should not be used (currently expected in MF mode)
// we skip the iteration
continue;
}
{
pdev->params.l2_cli_con_params[i].attributes = LM_CLIENT_ATTRIBUTES_RX | LM_CLIENT_ATTRIBUTES_TX | LM_CLIENT_ATTRIBUTES_REG_CLI;
}
else
{
}
}
return LM_STATUS_SUCCESS;
} /* lm_init_params */
/*******************************************************************************
* Description:
*
* Return:
******************************************************************************/
{
// initialize "product_version" to 0xffffffff so all platforms will have invalid values (but Windows that will update it later)
if(lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
if(lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
if (!IS_CHANNEL_VFDEV(pdev)) {
if(lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
}
// Get function num using me register
if (lm_status != LM_STATUS_SUCCESS) {
return lm_status;
}
// initialize pointers to init arrays (can only do this after we know which chip we are...)
// for PFs, VFs use PFDEV to access IRO
if ( lm_set_init_arrs(pdev) != 0 ) {
return LM_STATUS_UNKNOWN_ADAPTER;
}
} else {
/* For VF, we also get the vf-id here... since we need it from configuration space */
#ifdef VF_INVOLVED
{
}
#endif
}
#ifdef __LINUX
if (lm_is_function_after_flr(pdev))
{
if(lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
} else {
/* 8. Verify that the transaction-pending bit of each of the function in the Device Status Register in the PCIe is cleared. */
#ifdef __LINUX
DbgBreak();
}
}
#else
DbgBreak();
#endif
}
}
#endif
pdev->params.max_eth_including_vfs_conns = 1 << (LM_VF_MAX_RVFID_SIZE + LM_VF_CID_WND_SIZE(pdev) + 1);
// Registry parameters are read in this stage.
// As a result pdev->params.is_dcb_ndis_mp_en isn't valid yet.
{
// Add DCB multiple connections
#ifdef _VBD_
#else
#endif
}
else
{
#ifdef _VBD_
#else
#endif
}
}
else
{
}
if (lm_status != LM_STATUS_SUCCESS) {
return lm_status;
}
if (lm_status != LM_STATUS_SUCCESS) {
return lm_status;
}
if (lm_status != LM_STATUS_SUCCESS) {
return lm_status;
}
pdev->hw_info.mf_info.ext_id = 0xffff; /* invalid ovlan */ /* TBD - E1H: - what is the right value for Cisco? */
}
#ifdef VF_INVOLVED
}
#endif
(LM_DRIVER_MAJOR_VER << 24) |
(LM_DRIVER_MINOR_VER << 16) |
(LM_DRIVER_FIX_NUM << 8) |
// for debugging only (no other use)
(BCM_5710_FW_MINOR_VERSION << 16) |
(BCM_5710_FW_REVISION_VERSION<<8) |
/* get vnic parameters */
pdev->params.ovlan = VALID_OVLAN(OVLAN(pdev)) ? OVLAN(pdev) : 0; // TBD: verify it's the right value (with OfirH)
if IS_MULTI_VNIC(pdev)
{
}
{
// clc params
}
if (IS_CHANNEL_VFDEV(pdev))
{
}
else
{
if(lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
}
if(lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
if( LM_STATUS_SUCCESS != lm_status )
{
// Ediag may want to update the BC version. Don't fail lm_get_dev_info because of lm_mcp_cmd_init
// in no condition.
}
{
/* We're a single-function port on a mult-function path in a 4-port-mode environment... we need to support 1G */
{
}
}
/* Override the defaults with user configurations. */
if(lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
if(lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
return LM_STATUS_SUCCESS;
} /* lm_get_dev_info */
/*
*Function Name: lm_get_port_id_from_func_abs
*
*Parameters:
*
*Description:
* returns the port ID according to the func_abs_id
* Port0: 0,2,4,6
* Port1: 1,3,5,7
*
* Port0: 0,1,2,3,4,5,6,7
*
* E34P
* Port0: 0,1,4,5
* Port1: 2,3,6,7
*
*Returns: u8_t port_id
*
*/
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 )
{
do
{
if( CHIP_IS_E1x_PARAM( chip_num ) )
{
break;
}
switch( lm_chip_port_mode )
{
case LM_CHIP_PORT_MODE_2:
{
// we expect here only E2 or E3
port_id = 0;
}
break;
case LM_CHIP_PORT_MODE_4:
{
switch (modulus_res)
{
case 0:
case 1:
port_id = 0;
break;
case 2:
case 3:
port_id = 1;
break;
default:
break;
}
}
break;
default:
break;
} // switch lm_chip_port_mode
}while(0);
return port_id;
} /* lm_get_port_id_from_func_abs */
/*
*Function Name: lm_get_abs_func_vector
*
*Parameters:
*
*Description:
* returns vector of abs_func id's upon parameters
*
*Returns: u32_t abs_func_vector
*
*/
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 )
{
// TODO VF for T7.0
/*
The following table is mapping between abs func, ports and paths
|-----------------------------------------------|
|[#]| CHIP & Mode | PATH(s) | Port(s) | Func(s) |
|---|-------------|---------|---------|---------|
|[1]| E1.0 (SF) | (0) | 0,1 | (0,1) |
| | E1.5 SF | | 0,1 | (0,1) | (port is same as func)
|---|-------------|---------|---------|---------|
|[2]| E1.5 MF | (0) | 0,1 | 0-7 | 0,1,2,3,4,5,6,7 (port is %2 of func)
|---|-------------|---------|---------|---------|
|---|-------------|---------|---------|---------|
|---|-------------|---------|---------|---------|
|[5]| E34P SF | 0,1 | 0,1 | ---> | (Path 0) 0:port0 2:port1 | (Path 1) 1:port0 3:port1
|---|-------------|---------|---------|---------|
|[6]| E34P MF | 0,1 | 0,1 | ---> | (Path 0) 0,4:port0 2,6:port1 | (Path 1) 1,5:port0 3,7:port1 (57840)
|---|-------------|---------|---------|---------|
|[7]| E34P MF/SF | 0,1 | 0,1 | ---> | (Path 0) 0,4:port0 2:port1 | (Path 1) 1,5:port0 3:port1 (57800)
|---|-------------|---------|---------|---------|
*/
do
{
// [1]
{
SET_BIT( abs_func_vector, 0 );
break;
}
// [2]
{
SET_BIT( abs_func_vector, 0 );
break;
}
// If we got here chip should not be ealier than E2
// [3] [4] [5] [6]
switch ( chip_port_mode )
{
case LM_CHIP_PORT_MODE_2:
{
// we expect here only E2 or E3
if( b_multi_vnics_mode )
{
// [4]
break;
}
else
{
// [3]
break;
}
} // LM_CHIP_PORT_MODE_2
break;
case LM_CHIP_PORT_MODE_4:
{
if( b_multi_vnics_mode )
{
// [6]
if (chip_num != CHIP_NUM_57800)
{
}
// [7] In 57800 if we are multi function the other port can only be single function
else
{
}
break;
}
else
{
// [5]
if (chip_num != CHIP_NUM_57800)
{
}
// [7] We can't really know what's on the other port, so for this case where we are
// in 57800 single function, we assume multi-function and access all the functions
// so this might be case [5] but we can't know this.
else
{
}
break;
}
} // LM_CHIP_PORT_MODE_4
break;
default:
{
break;
}
} // CHIP_PORT_MODE
}while(0);
return abs_func_vector;
} /* lm_get_abs_func_vector */
{
{
return LM_STATUS_INVALID_PARAMETER ;
}
{
// check that shared memory is valid.
if((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) == (SHR_MEM_VALIDITY_DEV_INFO|SHR_MEM_VALIDITY_MB))
{
break;
}
}
return lm_status ;
}
{
return LM_STATUS_FAILURE;
}
}
if (cam_size != LM_KEEP_CURRENT_CAM_VALUE) {
}
if (mc_size != LM_KEEP_CURRENT_CAM_VALUE) {
if (CHIP_IS_E1(pdev)) {
} else {
}
}
return lm_status;
} /* lm_set_cam_params */
/*******************************************************************************
* Description:
*
* Return:
******************************************************************************/
{
{
{
}
else
{
}
}
} /* lm_cmng_calc_params */
/**
* @description
* Calculates BW according to current linespeed and MF
* configuration of the function in Mbps.
* @param pdev
* @param link_speed - Port rate in Mbps.
* @param vnic
*
* @return u16
* Return the max BW of the function in Mbps.
*/
{
//global vnic counter
{
// SD max BW in 100Mbps
}
else
{
// SI max BW in percentage from the link speed.
}
return max_bw;
}
{
{
break;
case PCI_CFG_NOT_TRUSTED:
break;
case PCI_CFG_TRUSTED:
break;
}
return b_assigned_to_vm;
}
{
(BCM_5710_FW_MINOR_VERSION << 8) |
(BCM_5710_FW_REVISION_VERSION << 16) |
(BCM_5710_FW_ENGINEERING_VERSION << 24) ;
u32_t real_fw_ver = REG_RD(pdev,0x2c0000); /* Read acitve FW version from 1st DWORD of XSTORM params*/
return (is_fw_valid);
}
/*
* Support for NSCI get OS driver version CQ70040
*/
/*Descripion: Write the client driver version
* to the shmem2 region
*/
{
{
return LM_STATUS_SUCCESS;
}
offset = drv_ver_offset + (pdev->params.pfunc_mb_id * sizeof(pdev->lm_cli_drv_ver_to_shmem.cli_drv_ver));
{
if (shmem2_size > offset)
{
{
}
}
}
return lm_status;
}
{
{
}
return res;
}