lm_niv.c revision d14abf155341d55053c76eeec58b787a456b753b
/*******************************************************************************
* 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:
*
*
* History:
* 11/29/10 Alon Elhanani Inception.
******************************************************************************/
#include "lm5710.h"
#include "mcp_shmem.h"
#include "mac_stats.h"
{
const niv_ramrod_state_t initial_state = b_enable ? NIV_RAMROD_SET_LOOPBACK_POSTED :NIV_RAMROD_CLEAR_LOOPBACK_POSTED ;
lm_status = lm_niv_post_command(pdev,RAMROD_CMD_ID_COMMON_FUNCTION_UPDATE, data_phys.as_u64, initial_state);
}
/**lm_niv_cli_update
* Update each client with new NIV default VLAN
*
* @param pdev the device to use
*
* @return lm_status_t LM_STATUS_SUCCESS on success, some other
* failure code on failure.
*/
{
{
// In this mode FW should remove all VLANS
silent_vlan_value = 0;
silent_vlan_mask = 0;
}
/* init l2 client conn param with default mtu values */
{
/* We want only Ethernet clients. For ethernet cid == client_id, we base the following check on that */
{
client_id = cid; // TODO: For ethernet client_id == cid... extra parameter added for terminology clearness incase this changes in the future.
if((LM_STATUS_ABORTED != lm_status) &&
(LM_STATUS_SUCCESS != lm_status))
{
return lm_status;
}
}
}
return LM_STATUS_SUCCESS;
}
{
// loopback tests will use default vlan 0x1 must be a value diffrent from zero,
// TODO : ask Barak that DIAG test will change the value in SHMEM.
if (LM_STATUS_SUCCESS != lm_status)
{
DbgBreakMsg("lm_niv_cli_update failed ");
}
}
{
// loopback tests revert values (has no real effect except debugging)
mf_info->default_vlan = 0;
}
{
if (b_enable)
{
#ifdef EDIAG
#else
#endif
}
else
{
#ifdef EDIAG
#else
#endif
}
return lm_status;
}
/**lm_niv_vif_enable
* enable current function or change its parameters. This
* function must be run in PASSIVE IRQL.
*
* @param pdev the device to use
*
* @return lm_status_t LM_STATUS_SUCCESS on success, some other
* failure code on failure.
*/
{
u16_t default_vlan = 0;
u8_t allowed_priorities = 0;
///Refresh MF CFG values
if (LM_STATUS_SUCCESS != lm_status)
{
return lm_status;
}
//Reconfigure rate-limit
///Send function-update ramrod and wait for completion
if (LM_STATUS_SUCCESS != lm_status)
{
return lm_status;
}
/* init l2 client conn param with default mtu values */
if (LM_STATUS_SUCCESS != lm_status)
{
DbgBreakMsg("lm_niv_cli_update failed ");
return lm_status;
}
///notify "link-up" to miniport
// cq64469 - verify that the link is up before reporting it as active to the miniport
{
}
return lm_status;
}
/** lm_niv_vif_disable
* disable current function. This function must be run in
* PASSIVE IRQL.
*
* @param pdev the device to use
*
* @return lm_status_t LM_STATUS_SUCCESS on success, some other
* failure code on failure.
*/
{
///indicate "link-down"
///Send function-update ramrod with vif_id=0xFFFF and wait for completion
if (LM_STATUS_SUCCESS != lm_status)
{
return lm_status;
}
return lm_status;
}
/**lm_niv_vif_delete
* Delete current function. . This function must be run in
* PASSIVE IRQL.
*
* @param pdev the device to use
*
* @return lm_status_t LM_STATUS_SUCCESS on success, some other
* failure code on failure.
*/
{
///Send a vif-list ramrod with VIF_LIST_RULE_CLEAR_FUNC opcode and wait for completion
lm_status = lm_niv_vif_list_update(pdev, VIF_LIST_RULE_CLEAR_FUNC, 0/*list_index*/, 0/*func_bit_map*/ ,ABS_FUNC_ID(pdev)/*func_to_clear*/);
if (LM_STATUS_SUCCESS != lm_status)
{
DbgBreakMsg("Failed to clear VIF lists on VIF delete.\n");
return lm_status;
}
if (LM_STATUS_SUCCESS != lm_status)
{
DbgBreakMsg("Failed to disable VIF on VIF delete.\n");
return lm_status;
}
return lm_status;
}
/**lm_chip_stats_to_niv_stats
* Copy relevant fields from driver statistics to the format
* written to the SHMEM for NIV stats.
*
* @param pdev the device to take the stats from
* @param p_afex_stats the SHMEM structure
*/
{
b10_l2_chip_statistics_t stats = {0};
fcoe_stats_info_t *fcoe_stats_mfw = &pdev->vars.stats.stats_mirror.stats_drv.drv_info_to_mfw.fcoe_stats;
sum_64 = stats.IfHCOutUcastPkts + fw_stats->fcoe.fcoe_tx_pkt_cnt + (HILO_U64(fcoe_stats_mfw->tx_frames_hi, fcoe_stats_mfw->tx_frames_lo ));
sum_64 = stats.IfHCOutUcastOctets + fw_stats->fcoe.fcoe_tx_byte_cnt + (HILO_U64(fcoe_stats_mfw->tx_bytes_hi, fcoe_stats_mfw->tx_bytes_lo ));
NIV_STATS_ASSIGN_HI_LO(p_afex_stats->tx_frames_dropped, fw_stats->eth_xstorm_common.client_statistics[LM_CLI_IDX_NDIS].error_drop_pkts);
sum_64 = stats.IfHCInUcastPkts + fw_stats->fcoe.fcoe_rx_pkt_cnt + (HILO_U64( fcoe_stats_mfw->rx_frames_hi, fcoe_stats_mfw->rx_frames_lo ));
sum_64 = stats.IfHCInUcastOctets + fw_stats->fcoe.fcoe_rx_byte_cnt + (HILO_U64( fcoe_stats_mfw->rx_bytes_hi, fcoe_stats_mfw->rx_bytes_lo ));
}
/**lm_niv_stats_get
* Update NIV statistics in SHMEM. This function runs in PASSIVE
* IRQL as an LPME.
*
* @param pdev the device to use
*/
{
u32_t output_offset = 0;
int bytes_written = 0;
struct afex_stats afex_stats_var = {0};
// verify that change in struct afex_stats won't corrupt our small stack
///Read from SHMEM2 the address where the response should be placed
///Write the response to the scratchpad field by field.
{
++field_ptr;
}
///ACK the MCP message
lm_mcp_cmd_send_recieve(pdev, lm_mcp_mb_header, DRV_MSG_CODE_AFEX_STATSGET_ACK, 0, MCP_CMD_DEFAULT_TIMEOUT, &mcp_resp);
}
/**lm_niv_vif_list_set
* Modify local information about VIF lists. This function runs
* in PASSIVE IRQL as an LPME. (PMF only)
*
* @param pdev the device to use
*/
{
u32_t list_bitmap = 0;
///Read VIF list id+bitfield from SHMEM2
///Send a vif-list ramrod with VIF_LIST_RULE_SET opcode and wait for completion
///ACK the MCP message
lm_mcp_cmd_send_recieve(pdev, lm_mcp_mb_header, DRV_MSG_CODE_AFEX_LISTSET_ACK, 0, MCP_CMD_DEFAULT_TIMEOUT, &mcp_resp);
}
/**lm_niv_vif_list_get
* Update NIV statistics in SHMEM. This function runs in PASSIVE
* IRQL as an LPME.
*
* @param pdev the device to use
*
*/
{
///Read list ID from SHMEM2
///Send a vif-list ramrod with VIF_LIST_RULE_GET opcode and wait for completion
///Write response to SHMEM and ACK the MCP message
lm_mcp_cmd_send_recieve(pdev, lm_mcp_mb_header, DRV_MSG_CODE_AFEX_LISTGET_ACK, pdev->slowpath_info.last_vif_list_bitmap, MCP_CMD_DEFAULT_TIMEOUT, &mcp_resp);
}
/**lm_niv_vif_set
* Handle a VIF-SET command. This function runs in PASSIVE IRQL
* as an LPME.
*
* @param pdev the device to use
*/
{
//lm_status_t lm_status = LM_STATUS_FAILURE;
u32_t func_mf_config = 0;
///read FUNC-DISABLED and FUNC-DELETED from func_mf_cfg
///if it's enable, call lm_niv_vif_enable
///if it's disable, call lm_niv_vif_disable
///if it's delete, call lm_niv_vif_delete
switch(val)
{
{
}
break;
{
}
break;
case 0: //neither=enabled
{
}
break;
default:
{
}
break;
}
///ACK the MCP message
lm_mcp_cmd_send_recieve(pdev, lm_mcp_mb_header, DRV_MSG_CODE_AFEX_VIFSET_ACK, 0, MCP_CMD_DEFAULT_TIMEOUT, &mcp_resp);
}
typedef struct _lm_niv_event_function_t
{
void (*function)(lm_device_t*);
/**lm_niv_event
* handle a NIV-related MCP general attention by scheduling the
* appropriate work item.
*
* @param pdev the device to use
* @param niv_event the DRIVER_STATUS flags that the MCP sent.
* It's assumed that only NIV-related flags are
* set.
*
* @return lm_status_t LM_STATUS_SUCCESS on success, some other
* failure code on failure.
*/
{
u32_t handled_events = 0;
static const lm_niv_event_function_t event_functions_arr[] = { {DRV_STATUS_AFEX_VIFSET_REQ, lm_niv_vif_set},
};
//for every possible flag: if it's set, schedule a WI with the associated function and set the same flag in handled_events
{
{
if (lm_status != LM_STATUS_SUCCESS)
{
return lm_status;
}
}
}
//make sure there we no unknown events set.
if (handled_events != niv_event)
{
return LM_STATUS_INVALID_PARAMETER;
}
return lm_status;
}