cregit-Linux how code gets into the kernel

Release 4.11 drivers/net/ethernet/qlogic/qed/qed_fcoe.c

/* QLogic qed NIC Driver
 * Copyright (c) 2015-2017  QLogic Corporation
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and /or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <linux/types.h>
#include <asm/byteorder.h>
#include <asm/param.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/log2.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/stddef.h>
#include <linux/string.h>
#include <linux/version.h>
#include <linux/workqueue.h>
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/spinlock.h>

#define __PREVENT_DUMP_MEM_ARR__

#define __PREVENT_PXP_GLOBAL_WIN__
#include "qed.h"
#include "qed_cxt.h"
#include "qed_dev_api.h"
#include "qed_fcoe.h"
#include "qed_hsi.h"
#include "qed_hw.h"
#include "qed_int.h"
#include "qed_ll2.h"
#include "qed_mcp.h"
#include "qed_reg_addr.h"
#include "qed_sp.h"
#include "qed_sriov.h"
#include <linux/qed/qed_fcoe_if.h>


struct qed_fcoe_conn {
	
struct list_head list_entry;
	
bool free_on_delete;

	
u16 conn_id;
	
u32 icid;
	
u32 fw_cid;
	
u8 layer_code;

	
dma_addr_t sq_pbl_addr;
	
dma_addr_t sq_curr_page_addr;
	
dma_addr_t sq_next_page_addr;
	
dma_addr_t xferq_pbl_addr;
	
void *xferq_pbl_addr_virt_addr;
	
dma_addr_t xferq_addr[4];
	
void *xferq_addr_virt_addr[4];
	
dma_addr_t confq_pbl_addr;
	
void *confq_pbl_addr_virt_addr;
	
dma_addr_t confq_addr[2];
	
void *confq_addr_virt_addr[2];

	
dma_addr_t terminate_params;

	
u16 dst_mac_addr_lo;
	
u16 dst_mac_addr_mid;
	
u16 dst_mac_addr_hi;
	
u16 src_mac_addr_lo;
	
u16 src_mac_addr_mid;
	
u16 src_mac_addr_hi;

	
u16 tx_max_fc_pay_len;
	
u16 e_d_tov_timer_val;
	
u16 rec_tov_timer_val;
	
u16 rx_max_fc_pay_len;
	
u16 vlan_tag;
	
u16 physical_q0;

	
struct fc_addr_nw s_id;
	
u8 max_conc_seqs_c3;
	
struct fc_addr_nw d_id;
	
u8 flags;
	
u8 def_q_idx;
};


static int qed_sp_fcoe_func_start(struct qed_hwfn *p_hwfn, enum spq_mode comp_mode, struct qed_spq_comp_cb *p_comp_addr) { struct qed_fcoe_pf_params *fcoe_pf_params = NULL; struct fcoe_init_ramrod_params *p_ramrod = NULL; struct fcoe_init_func_ramrod_data *p_data; struct fcoe_conn_context *p_cxt = NULL; struct qed_spq_entry *p_ent = NULL; struct qed_sp_init_data init_data; struct qed_cxt_info cxt_info; u32 dummy_cid; int rc = 0; u16 tmp; u8 i; /* Get SPQ entry */ memset(&init_data, 0, sizeof(init_data)); init_data.cid = qed_spq_get_cid(p_hwfn); init_data.opaque_fid = p_hwfn->hw_info.opaque_fid; init_data.comp_mode = comp_mode; init_data.p_comp_data = p_comp_addr; rc = qed_sp_init_request(p_hwfn, &p_ent, FCOE_RAMROD_CMD_ID_INIT_FUNC, PROTOCOLID_FCOE, &init_data); if (rc) return rc; p_ramrod = &p_ent->ramrod.fcoe_init; p_data = &p_ramrod->init_ramrod_data; fcoe_pf_params = &p_hwfn->pf_params.fcoe_pf_params; p_data->mtu = cpu_to_le16(fcoe_pf_params->mtu); tmp = cpu_to_le16(fcoe_pf_params->sq_num_pbl_pages); p_data->sq_num_pages_in_pbl = tmp; rc = qed_cxt_acquire_cid(p_hwfn, PROTOCOLID_FCOE, &dummy_cid); if (rc) return rc; cxt_info.iid = dummy_cid; rc = qed_cxt_get_cid_info(p_hwfn, &cxt_info); if (rc) { DP_NOTICE(p_hwfn, "Cannot find context info for dummy cid=%d\n", dummy_cid); return rc; } p_cxt = cxt_info.p_cxt; SET_FIELD(p_cxt->tstorm_ag_context.flags3, TSTORM_FCOE_CONN_AG_CTX_DUMMY_TIMER_CF_EN, 1); fcoe_pf_params->dummy_icid = (u16)dummy_cid; tmp = cpu_to_le16(fcoe_pf_params->num_tasks); p_data->func_params.num_tasks = tmp; p_data->func_params.log_page_size = fcoe_pf_params->log_page_size; p_data->func_params.debug_mode = fcoe_pf_params->debug_mode; DMA_REGPAIR_LE(p_data->q_params.glbl_q_params_addr, fcoe_pf_params->glbl_q_params_addr); tmp = cpu_to_le16(fcoe_pf_params->cq_num_entries); p_data->q_params.cq_num_entries = tmp; tmp = cpu_to_le16(fcoe_pf_params->cmdq_num_entries); p_data->q_params.cmdq_num_entries = tmp; tmp = fcoe_pf_params->num_cqs; p_data->q_params.num_queues = (u8)tmp; tmp = (u16)p_hwfn->hw_info.resc_start[QED_CMDQS_CQS]; p_data->q_params.queue_relative_offset = (u8)tmp; for (i = 0; i < fcoe_pf_params->num_cqs; i++) { tmp = cpu_to_le16(p_hwfn->sbs_info[i]->igu_sb_id); p_data->q_params.cq_cmdq_sb_num_arr[i] = tmp; } p_data->q_params.cq_sb_pi = fcoe_pf_params->gl_rq_pi; p_data->q_params.cmdq_sb_pi = fcoe_pf_params->gl_cmd_pi; p_data->q_params.bdq_resource_id = FCOE_BDQ_ID(p_hwfn->port_id); DMA_REGPAIR_LE(p_data->q_params.bdq_pbl_base_address[BDQ_ID_RQ], fcoe_pf_params->bdq_pbl_base_addr[BDQ_ID_RQ]); p_data->q_params.bdq_pbl_num_entries[BDQ_ID_RQ] = fcoe_pf_params->bdq_pbl_num_entries[BDQ_ID_RQ]; tmp = fcoe_pf_params->bdq_xoff_threshold[BDQ_ID_RQ]; p_data->q_params.bdq_xoff_threshold[BDQ_ID_RQ] = cpu_to_le16(tmp); tmp = fcoe_pf_params->bdq_xon_threshold[BDQ_ID_RQ]; p_data->q_params.bdq_xon_threshold[BDQ_ID_RQ] = cpu_to_le16(tmp); DMA_REGPAIR_LE(p_data->q_params.bdq_pbl_base_address[BDQ_ID_IMM_DATA], fcoe_pf_params->bdq_pbl_base_addr[BDQ_ID_IMM_DATA]); p_data->q_params.bdq_pbl_num_entries[BDQ_ID_IMM_DATA] = fcoe_pf_params->bdq_pbl_num_entries[BDQ_ID_IMM_DATA]; tmp = fcoe_pf_params->bdq_xoff_threshold[BDQ_ID_IMM_DATA]; p_data->q_params.bdq_xoff_threshold[BDQ_ID_IMM_DATA] = cpu_to_le16(tmp); tmp = fcoe_pf_params->bdq_xon_threshold[BDQ_ID_IMM_DATA]; p_data->q_params.bdq_xon_threshold[BDQ_ID_IMM_DATA] = cpu_to_le16(tmp); tmp = fcoe_pf_params->rq_buffer_size; p_data->q_params.rq_buffer_size = cpu_to_le16(tmp); if (fcoe_pf_params->is_target) { SET_FIELD(p_data->q_params.q_validity, SCSI_INIT_FUNC_QUEUES_RQ_VALID, 1); if (p_data->q_params.bdq_pbl_num_entries[BDQ_ID_IMM_DATA]) SET_FIELD(p_data->q_params.q_validity, SCSI_INIT_FUNC_QUEUES_IMM_DATA_VALID, 1); SET_FIELD(p_data->q_params.q_validity, SCSI_INIT_FUNC_QUEUES_CMD_VALID, 1); } else { SET_FIELD(p_data->q_params.q_validity, SCSI_INIT_FUNC_QUEUES_RQ_VALID, 1); } rc = qed_spq_post(p_hwfn, p_ent, NULL); return rc; }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi744100.00%1100.00%
Total744100.00%1100.00%


static int qed_sp_fcoe_conn_offload(struct qed_hwfn *p_hwfn, struct qed_fcoe_conn *p_conn, enum spq_mode comp_mode, struct qed_spq_comp_cb *p_comp_addr) { struct fcoe_conn_offload_ramrod_params *p_ramrod = NULL; struct fcoe_conn_offload_ramrod_data *p_data; struct qed_spq_entry *p_ent = NULL; struct qed_sp_init_data init_data; u16 pq_id = 0, tmp; int rc; /* Get SPQ entry */ memset(&init_data, 0, sizeof(init_data)); init_data.cid = p_conn->icid; init_data.opaque_fid = p_hwfn->hw_info.opaque_fid; init_data.comp_mode = comp_mode; init_data.p_comp_data = p_comp_addr; rc = qed_sp_init_request(p_hwfn, &p_ent, FCOE_RAMROD_CMD_ID_OFFLOAD_CONN, PROTOCOLID_FCOE, &init_data); if (rc) return rc; p_ramrod = &p_ent->ramrod.fcoe_conn_ofld; p_data = &p_ramrod->offload_ramrod_data; /* Transmission PQ is the first of the PF */ pq_id = qed_get_qm_pq(p_hwfn, PROTOCOLID_FCOE, NULL); p_conn->physical_q0 = cpu_to_le16(pq_id); p_data->physical_q0 = cpu_to_le16(pq_id); p_data->conn_id = cpu_to_le16(p_conn->conn_id); DMA_REGPAIR_LE(p_data->sq_pbl_addr, p_conn->sq_pbl_addr); DMA_REGPAIR_LE(p_data->sq_curr_page_addr, p_conn->sq_curr_page_addr); DMA_REGPAIR_LE(p_data->sq_next_page_addr, p_conn->sq_next_page_addr); DMA_REGPAIR_LE(p_data->xferq_pbl_addr, p_conn->xferq_pbl_addr); DMA_REGPAIR_LE(p_data->xferq_curr_page_addr, p_conn->xferq_addr[0]); DMA_REGPAIR_LE(p_data->xferq_next_page_addr, p_conn->xferq_addr[1]); DMA_REGPAIR_LE(p_data->respq_pbl_addr, p_conn->confq_pbl_addr); DMA_REGPAIR_LE(p_data->respq_curr_page_addr, p_conn->confq_addr[0]); DMA_REGPAIR_LE(p_data->respq_next_page_addr, p_conn->confq_addr[1]); p_data->dst_mac_addr_lo = cpu_to_le16(p_conn->dst_mac_addr_lo); p_data->dst_mac_addr_mid = cpu_to_le16(p_conn->dst_mac_addr_mid); p_data->dst_mac_addr_hi = cpu_to_le16(p_conn->dst_mac_addr_hi); p_data->src_mac_addr_lo = cpu_to_le16(p_conn->src_mac_addr_lo); p_data->src_mac_addr_mid = cpu_to_le16(p_conn->src_mac_addr_mid); p_data->src_mac_addr_hi = cpu_to_le16(p_conn->src_mac_addr_hi); tmp = cpu_to_le16(p_conn->tx_max_fc_pay_len); p_data->tx_max_fc_pay_len = tmp; tmp = cpu_to_le16(p_conn->e_d_tov_timer_val); p_data->e_d_tov_timer_val = tmp; tmp = cpu_to_le16(p_conn->rec_tov_timer_val); p_data->rec_rr_tov_timer_val = tmp; tmp = cpu_to_le16(p_conn->rx_max_fc_pay_len); p_data->rx_max_fc_pay_len = tmp; p_data->vlan_tag = cpu_to_le16(p_conn->vlan_tag); p_data->s_id.addr_hi = p_conn->s_id.addr_hi; p_data->s_id.addr_mid = p_conn->s_id.addr_mid; p_data->s_id.addr_lo = p_conn->s_id.addr_lo; p_data->max_conc_seqs_c3 = p_conn->max_conc_seqs_c3; p_data->d_id.addr_hi = p_conn->d_id.addr_hi; p_data->d_id.addr_mid = p_conn->d_id.addr_mid; p_data->d_id.addr_lo = p_conn->d_id.addr_lo; p_data->flags = p_conn->flags; p_data->def_q_idx = p_conn->def_q_idx; return qed_spq_post(p_hwfn, p_ent, NULL); }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi537100.00%1100.00%
Total537100.00%1100.00%


static int qed_sp_fcoe_conn_destroy(struct qed_hwfn *p_hwfn, struct qed_fcoe_conn *p_conn, enum spq_mode comp_mode, struct qed_spq_comp_cb *p_comp_addr) { struct fcoe_conn_terminate_ramrod_params *p_ramrod = NULL; struct qed_spq_entry *p_ent = NULL; struct qed_sp_init_data init_data; int rc = 0; /* Get SPQ entry */ memset(&init_data, 0, sizeof(init_data)); init_data.cid = p_conn->icid; init_data.opaque_fid = p_hwfn->hw_info.opaque_fid; init_data.comp_mode = comp_mode; init_data.p_comp_data = p_comp_addr; rc = qed_sp_init_request(p_hwfn, &p_ent, FCOE_RAMROD_CMD_ID_TERMINATE_CONN, PROTOCOLID_FCOE, &init_data); if (rc) return rc; p_ramrod = &p_ent->ramrod.fcoe_conn_terminate; DMA_REGPAIR_LE(p_ramrod->terminate_ramrod_data.terminate_params_addr, p_conn->terminate_params); return qed_spq_post(p_hwfn, p_ent, NULL); }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi148100.00%1100.00%
Total148100.00%1100.00%


static int qed_sp_fcoe_func_stop(struct qed_hwfn *p_hwfn, enum spq_mode comp_mode, struct qed_spq_comp_cb *p_comp_addr) { struct qed_ptt *p_ptt = p_hwfn->p_main_ptt; struct qed_spq_entry *p_ent = NULL; struct qed_sp_init_data init_data; u32 active_segs = 0; int rc = 0; /* Get SPQ entry */ memset(&init_data, 0, sizeof(init_data)); init_data.cid = p_hwfn->pf_params.fcoe_pf_params.dummy_icid; init_data.opaque_fid = p_hwfn->hw_info.opaque_fid; init_data.comp_mode = comp_mode; init_data.p_comp_data = p_comp_addr; rc = qed_sp_init_request(p_hwfn, &p_ent, FCOE_RAMROD_CMD_ID_DESTROY_FUNC, PROTOCOLID_FCOE, &init_data); if (rc) return rc; active_segs = qed_rd(p_hwfn, p_ptt, TM_REG_PF_ENABLE_TASK); active_segs &= ~BIT(QED_CXT_FCOE_TID_SEG); qed_wr(p_hwfn, p_ptt, TM_REG_PF_ENABLE_TASK, active_segs); return qed_spq_post(p_hwfn, p_ent, NULL); }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi162100.00%1100.00%
Total162100.00%1100.00%


static int qed_fcoe_allocate_connection(struct qed_hwfn *p_hwfn, struct qed_fcoe_conn **p_out_conn) { struct qed_fcoe_conn *p_conn = NULL; void *p_addr; u32 i; spin_lock_bh(&p_hwfn->p_fcoe_info->lock); if (!list_empty(&p_hwfn->p_fcoe_info->free_list)) p_conn = list_first_entry(&p_hwfn->p_fcoe_info->free_list, struct qed_fcoe_conn, list_entry); if (p_conn) { list_del(&p_conn->list_entry); spin_unlock_bh(&p_hwfn->p_fcoe_info->lock); *p_out_conn = p_conn; return 0; } spin_unlock_bh(&p_hwfn->p_fcoe_info->lock); p_conn = kzalloc(sizeof(*p_conn), GFP_KERNEL); if (!p_conn) return -ENOMEM; p_addr = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev, QED_CHAIN_PAGE_SIZE, &p_conn->xferq_pbl_addr, GFP_KERNEL); if (!p_addr) goto nomem_pbl_xferq; p_conn->xferq_pbl_addr_virt_addr = p_addr; for (i = 0; i < ARRAY_SIZE(p_conn->xferq_addr); i++) { p_addr = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev, QED_CHAIN_PAGE_SIZE, &p_conn->xferq_addr[i], GFP_KERNEL); if (!p_addr) goto nomem_xferq; p_conn->xferq_addr_virt_addr[i] = p_addr; p_addr = p_conn->xferq_pbl_addr_virt_addr; ((dma_addr_t *)p_addr)[i] = p_conn->xferq_addr[i]; } p_addr = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev, QED_CHAIN_PAGE_SIZE, &p_conn->confq_pbl_addr, GFP_KERNEL); if (!p_addr) goto nomem_xferq; p_conn->confq_pbl_addr_virt_addr = p_addr; for (i = 0; i < ARRAY_SIZE(p_conn->confq_addr); i++) { p_addr = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev, QED_CHAIN_PAGE_SIZE, &p_conn->confq_addr[i], GFP_KERNEL); if (!p_addr) goto nomem_confq; p_conn->confq_addr_virt_addr[i] = p_addr; p_addr = p_conn->confq_pbl_addr_virt_addr; ((dma_addr_t *)p_addr)[i] = p_conn->confq_addr[i]; } p_conn->free_on_delete = true; *p_out_conn = p_conn; return 0; nomem_confq: dma_free_coherent(&p_hwfn->cdev->pdev->dev, QED_CHAIN_PAGE_SIZE, p_conn->confq_pbl_addr_virt_addr, p_conn->confq_pbl_addr); for (i = 0; i < ARRAY_SIZE(p_conn->confq_addr); i++) if (p_conn->confq_addr_virt_addr[i]) dma_free_coherent(&p_hwfn->cdev->pdev->dev, QED_CHAIN_PAGE_SIZE, p_conn->confq_addr_virt_addr[i], p_conn->confq_addr[i]); nomem_xferq: dma_free_coherent(&p_hwfn->cdev->pdev->dev, QED_CHAIN_PAGE_SIZE, p_conn->xferq_pbl_addr_virt_addr, p_conn->xferq_pbl_addr); for (i = 0; i < ARRAY_SIZE(p_conn->xferq_addr); i++) if (p_conn->xferq_addr_virt_addr[i]) dma_free_coherent(&p_hwfn->cdev->pdev->dev, QED_CHAIN_PAGE_SIZE, p_conn->xferq_addr_virt_addr[i], p_conn->xferq_addr[i]); nomem_pbl_xferq: kfree(p_conn); return -ENOMEM; }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi566100.00%1100.00%
Total566100.00%1100.00%


static void qed_fcoe_free_connection(struct qed_hwfn *p_hwfn, struct qed_fcoe_conn *p_conn) { u32 i; if (!p_conn) return; if (p_conn->confq_pbl_addr_virt_addr) dma_free_coherent(&p_hwfn->cdev->pdev->dev, QED_CHAIN_PAGE_SIZE, p_conn->confq_pbl_addr_virt_addr, p_conn->confq_pbl_addr); for (i = 0; i < ARRAY_SIZE(p_conn->confq_addr); i++) { if (!p_conn->confq_addr_virt_addr[i]) continue; dma_free_coherent(&p_hwfn->cdev->pdev->dev, QED_CHAIN_PAGE_SIZE, p_conn->confq_addr_virt_addr[i], p_conn->confq_addr[i]); } if (p_conn->xferq_pbl_addr_virt_addr) dma_free_coherent(&p_hwfn->cdev->pdev->dev, QED_CHAIN_PAGE_SIZE, p_conn->xferq_pbl_addr_virt_addr, p_conn->xferq_pbl_addr); for (i = 0; i < ARRAY_SIZE(p_conn->xferq_addr); i++) { if (!p_conn->xferq_addr_virt_addr[i]) continue; dma_free_coherent(&p_hwfn->cdev->pdev->dev, QED_CHAIN_PAGE_SIZE, p_conn->xferq_addr_virt_addr[i], p_conn->xferq_addr[i]); } kfree(p_conn); }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi204100.00%1100.00%
Total204100.00%1100.00%


static void __iomem *qed_fcoe_get_db_addr(struct qed_hwfn *p_hwfn, u32 cid) { return (u8 __iomem *)p_hwfn->doorbells + qed_db_addr(cid, DQ_DEMS_LEGACY); }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi33100.00%1100.00%
Total33100.00%1100.00%


static void __iomem *qed_fcoe_get_primary_bdq_prod(struct qed_hwfn *p_hwfn, u8 bdq_id) { u8 bdq_function_id = FCOE_BDQ_ID(p_hwfn->port_id); return (u8 __iomem *)p_hwfn->regview + GTT_BAR0_MAP_REG_MSDM_RAM + MSTORM_SCSI_BDQ_EXT_PROD_OFFSET(bdq_function_id, bdq_id); }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi45100.00%1100.00%
Total45100.00%1100.00%


static void __iomem *qed_fcoe_get_secondary_bdq_prod(struct qed_hwfn *p_hwfn, u8 bdq_id) { u8 bdq_function_id = FCOE_BDQ_ID(p_hwfn->port_id); return (u8 __iomem *)p_hwfn->regview + GTT_BAR0_MAP_REG_TSDM_RAM + TSTORM_SCSI_BDQ_EXT_PROD_OFFSET(bdq_function_id, bdq_id); }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi45100.00%1100.00%
Total45100.00%1100.00%


struct qed_fcoe_info *qed_fcoe_alloc(struct qed_hwfn *p_hwfn) { struct qed_fcoe_info *p_fcoe_info; /* Allocate LL2's set struct */ p_fcoe_info = kzalloc(sizeof(*p_fcoe_info), GFP_KERNEL); if (!p_fcoe_info) { DP_NOTICE(p_hwfn, "Failed to allocate qed_fcoe_info'\n"); return NULL; } INIT_LIST_HEAD(&p_fcoe_info->free_list); return p_fcoe_info; }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi59100.00%1100.00%
Total59100.00%1100.00%


void qed_fcoe_setup(struct qed_hwfn *p_hwfn, struct qed_fcoe_info *p_fcoe_info) { struct fcoe_task_context *p_task_ctx = NULL; int rc; u32 i; spin_lock_init(&p_fcoe_info->lock); for (i = 0; i < p_hwfn->pf_params.fcoe_pf_params.num_tasks; i++) { rc = qed_cxt_get_task_ctx(p_hwfn, i, QED_CTX_WORKING_MEM, (void **)&p_task_ctx); if (rc) continue; memset(p_task_ctx, 0, sizeof(struct fcoe_task_context)); SET_FIELD(p_task_ctx->timer_context.logical_client_0, TIMERS_CONTEXT_VALIDLC0, 1); SET_FIELD(p_task_ctx->timer_context.logical_client_1, TIMERS_CONTEXT_VALIDLC1, 1); SET_FIELD(p_task_ctx->tstorm_ag_context.flags0, TSTORM_FCOE_TASK_AG_CTX_CONNECTION_TYPE, 1); } }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi133100.00%1100.00%
Total133100.00%1100.00%


void qed_fcoe_free(struct qed_hwfn *p_hwfn, struct qed_fcoe_info *p_fcoe_info) { struct qed_fcoe_conn *p_conn = NULL; if (!p_fcoe_info) return; while (!list_empty(&p_fcoe_info->free_list)) { p_conn = list_first_entry(&p_fcoe_info->free_list, struct qed_fcoe_conn, list_entry); if (!p_conn) break; list_del(&p_conn->list_entry); qed_fcoe_free_connection(p_hwfn, p_conn); } kfree(p_fcoe_info); }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi82100.00%1100.00%
Total82100.00%1100.00%


static int qed_fcoe_acquire_connection(struct qed_hwfn *p_hwfn, struct qed_fcoe_conn *p_in_conn, struct qed_fcoe_conn **p_out_conn) { struct qed_fcoe_conn *p_conn = NULL; int rc = 0; u32 icid; spin_lock_bh(&p_hwfn->p_fcoe_info->lock); rc = qed_cxt_acquire_cid(p_hwfn, PROTOCOLID_FCOE, &icid); spin_unlock_bh(&p_hwfn->p_fcoe_info->lock); if (rc) return rc; /* Use input connection [if provided] or allocate a new one */ if (p_in_conn) { p_conn = p_in_conn; } else { rc = qed_fcoe_allocate_connection(p_hwfn, &p_conn); if (rc) { spin_lock_bh(&p_hwfn->p_fcoe_info->lock); qed_cxt_release_cid(p_hwfn, icid); spin_unlock_bh(&p_hwfn->p_fcoe_info->lock); return rc; } } p_conn->icid = icid; p_conn->fw_cid = (p_hwfn->hw_info.opaque_fid << 16) | icid; *p_out_conn = p_conn; return rc; }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi166100.00%1100.00%
Total166100.00%1100.00%


static void qed_fcoe_release_connection(struct qed_hwfn *p_hwfn, struct qed_fcoe_conn *p_conn) { spin_lock_bh(&p_hwfn->p_fcoe_info->lock); list_add_tail(&p_conn->list_entry, &p_hwfn->p_fcoe_info->free_list); qed_cxt_release_cid(p_hwfn, p_conn->icid); spin_unlock_bh(&p_hwfn->p_fcoe_info->lock); }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi60100.00%1100.00%
Total60100.00%1100.00%


static void _qed_fcoe_get_tstats(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, struct qed_fcoe_stats *p_stats) { struct fcoe_rx_stat tstats; u32 tstats_addr; memset(&tstats, 0, sizeof(tstats)); tstats_addr = BAR0_MAP_REG_TSDM_RAM + TSTORM_FCOE_RX_STATS_OFFSET(p_hwfn->rel_pf_id); qed_memcpy_from(p_hwfn, p_ptt, &tstats, tstats_addr, sizeof(tstats)); p_stats->fcoe_rx_byte_cnt = HILO_64_REGPAIR(tstats.fcoe_rx_byte_cnt); p_stats->fcoe_rx_data_pkt_cnt = HILO_64_REGPAIR(tstats.fcoe_rx_data_pkt_cnt); p_stats->fcoe_rx_xfer_pkt_cnt = HILO_64_REGPAIR(tstats.fcoe_rx_xfer_pkt_cnt); p_stats->fcoe_rx_other_pkt_cnt = HILO_64_REGPAIR(tstats.fcoe_rx_other_pkt_cnt); p_stats->fcoe_silent_drop_pkt_cmdq_full_cnt = le32_to_cpu(tstats.fcoe_silent_drop_pkt_cmdq_full_cnt); p_stats->fcoe_silent_drop_pkt_rq_full_cnt = le32_to_cpu(tstats.fcoe_silent_drop_pkt_rq_full_cnt); p_stats->fcoe_silent_drop_pkt_crc_error_cnt = le32_to_cpu(tstats.fcoe_silent_drop_pkt_crc_error_cnt); p_stats->fcoe_silent_drop_pkt_task_invalid_cnt = le32_to_cpu(tstats.fcoe_silent_drop_pkt_task_invalid_cnt); p_stats->fcoe_silent_drop_total_pkt_cnt = le32_to_cpu(tstats.fcoe_silent_drop_total_pkt_cnt); }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi168100.00%1100.00%
Total168100.00%1100.00%


static void _qed_fcoe_get_pstats(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, struct qed_fcoe_stats *p_stats) { struct fcoe_tx_stat pstats; u32 pstats_addr; memset(&pstats, 0, sizeof(pstats)); pstats_addr = BAR0_MAP_REG_PSDM_RAM + PSTORM_FCOE_TX_STATS_OFFSET(p_hwfn->rel_pf_id); qed_memcpy_from(p_hwfn, p_ptt, &pstats, pstats_addr, sizeof(pstats)); p_stats->fcoe_tx_byte_cnt = HILO_64_REGPAIR(pstats.fcoe_tx_byte_cnt); p_stats->fcoe_tx_data_pkt_cnt = HILO_64_REGPAIR(pstats.fcoe_tx_data_pkt_cnt); p_stats->fcoe_tx_xfer_pkt_cnt = HILO_64_REGPAIR(pstats.fcoe_tx_xfer_pkt_cnt); p_stats->fcoe_tx_other_pkt_cnt = HILO_64_REGPAIR(pstats.fcoe_tx_other_pkt_cnt); }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi113100.00%1100.00%
Total113100.00%1100.00%


static int qed_fcoe_get_stats(struct qed_hwfn *p_hwfn, struct qed_fcoe_stats *p_stats) { struct qed_ptt *p_ptt; memset(p_stats, 0, sizeof(*p_stats)); p_ptt = qed_ptt_acquire(p_hwfn); if (!p_ptt) { DP_ERR(p_hwfn, "Failed to acquire ptt\n"); return -EINVAL; } _qed_fcoe_get_tstats(p_hwfn, p_ptt, p_stats); _qed_fcoe_get_pstats(p_hwfn, p_ptt, p_stats); qed_ptt_release(p_hwfn, p_ptt); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi87100.00%1100.00%
Total87100.00%1100.00%

struct qed_hash_fcoe_con { struct hlist_node node; struct qed_fcoe_conn *con; };
static int qed_fill_fcoe_dev_info(struct qed_dev *cdev, struct qed_dev_fcoe_info *info) { struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); int rc; memset(info, 0, sizeof(*info)); rc = qed_fill_dev_info(cdev, &info->common); info->primary_dbq_rq_addr = qed_fcoe_get_primary_bdq_prod(hwfn, BDQ_ID_RQ); info->secondary_bdq_rq_addr = qed_fcoe_get_secondary_bdq_prod(hwfn, BDQ_ID_RQ); return rc; }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi79100.00%1100.00%
Total79100.00%1100.00%


static void qed_register_fcoe_ops(struct qed_dev *cdev, struct qed_fcoe_cb_ops *ops, void *cookie) { cdev->protocol_ops.fcoe = ops; cdev->ops_cookie = cookie; }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi34100.00%1100.00%
Total34100.00%1100.00%


static struct qed_hash_fcoe_con *qed_fcoe_get_hash(struct qed_dev *cdev, u32 handle) { struct qed_hash_fcoe_con *hash_con = NULL; if (!(cdev->flags & QED_FLAG_STORAGE_STARTED)) return NULL; hash_for_each_possible(cdev->connections, hash_con, node, handle) { if (hash_con->con->icid == handle) break; } if (!hash_con || (hash_con->con->icid != handle)) return NULL; return hash_con; }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi81100.00%1100.00%
Total81100.00%1100.00%


static int qed_fcoe_stop(struct qed_dev *cdev) { int rc; if (!(cdev->flags & QED_FLAG_STORAGE_STARTED)) { DP_NOTICE(cdev, "fcoe already stopped\n"); return 0; } if (!hash_empty(cdev->connections)) { DP_NOTICE(cdev, "Can't stop fcoe - not all connections were returned\n"); return -EINVAL; } /* Stop the fcoe */ rc = qed_sp_fcoe_func_stop(QED_LEADING_HWFN(cdev), QED_SPQ_MODE_EBLOCK, NULL); cdev->flags &= ~QED_FLAG_STORAGE_STARTED; return rc; }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi85100.00%1100.00%
Total85100.00%1100.00%


static int qed_fcoe_start(struct qed_dev *cdev, struct qed_fcoe_tid *tasks) { int rc; if (cdev->flags & QED_FLAG_STORAGE_STARTED) { DP_NOTICE(cdev, "fcoe already started;\n"); return 0; } rc = qed_sp_fcoe_func_start(QED_LEADING_HWFN(cdev), QED_SPQ_MODE_EBLOCK, NULL); if (rc) { DP_NOTICE(cdev, "Failed to start fcoe\n"); return rc; } cdev->flags |= QED_FLAG_STORAGE_STARTED; hash_init(cdev->connections); if (tasks) { struct qed_tid_mem *tid_info = kzalloc(sizeof(*tid_info), GFP_ATOMIC); if (!tid_info) { DP_NOTICE(cdev, "Failed to allocate tasks information\n"); qed_fcoe_stop(cdev); return -ENOMEM; } rc = qed_cxt_get_tid_mem_info(QED_LEADING_HWFN(cdev), tid_info); if (rc) { DP_NOTICE(cdev, "Failed to gather task information\n"); qed_fcoe_stop(cdev); kfree(tid_info); return rc; } /* Fill task information */ tasks->size = tid_info->tid_size; tasks->num_tids_per_block = tid_info->num_tids_per_block; memcpy(tasks->blocks, tid_info->blocks, MAX_TID_BLOCKS_FCOE * sizeof(u8 *)); kfree(tid_info); } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi209100.00%1100.00%
Total209100.00%1100.00%


static int qed_fcoe_acquire_conn(struct qed_dev *cdev, u32 *handle, u32 *fw_cid, void __iomem **p_doorbell) { struct qed_hash_fcoe_con *hash_con; int rc; /* Allocate a hashed connection */ hash_con = kzalloc(sizeof(*hash_con), GFP_KERNEL); if (!hash_con) { DP_NOTICE(cdev, "Failed to allocate hashed connection\n"); return -ENOMEM; } /* Acquire the connection */ rc = qed_fcoe_acquire_connection(QED_LEADING_HWFN(cdev), NULL, &hash_con->con); if (rc) { DP_NOTICE(cdev, "Failed to acquire Connection\n"); kfree(hash_con); return rc; } /* Added the connection to hash table */ *handle = hash_con->con->icid; *fw_cid = hash_con->con->fw_cid; hash_add(cdev->connections, &hash_con->node, *handle); if (p_doorbell) *p_doorbell = qed_fcoe_get_db_addr(QED_LEADING_HWFN(cdev), *handle); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi159100.00%1100.00%
Total159100.00%1100.00%


static int qed_fcoe_release_conn(struct qed_dev *cdev, u32 handle) { struct qed_hash_fcoe_con *hash_con; hash_con = qed_fcoe_get_hash(cdev, handle); if (!hash_con) { DP_NOTICE(cdev, "Failed to find connection for handle %d\n", handle); return -EINVAL; } hlist_del(&hash_con->node); qed_fcoe_release_connection(QED_LEADING_HWFN(cdev), hash_con->con); kfree(hash_con); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi76100.00%1100.00%
Total76100.00%1100.00%


static int qed_fcoe_offload_conn(struct qed_dev *cdev, u32 handle, struct qed_fcoe_params_offload *conn_info) { struct qed_hash_fcoe_con *hash_con; struct qed_fcoe_conn *con; hash_con = qed_fcoe_get_hash(cdev, handle); if (!hash_con) { DP_NOTICE(cdev, "Failed to find connection for handle %d\n", handle); return -EINVAL; } /* Update the connection with information from the params */ con = hash_con->con; con->sq_pbl_addr = conn_info->sq_pbl_addr; con->sq_curr_page_addr = conn_info->sq_curr_page_addr; con->sq_next_page_addr = conn_info->sq_next_page_addr; con->tx_max_fc_pay_len = conn_info->tx_max_fc_pay_len; con->e_d_tov_timer_val = conn_info->e_d_tov_timer_val; con->rec_tov_timer_val = conn_info->rec_tov_timer_val; con->rx_max_fc_pay_len = conn_info->rx_max_fc_pay_len; con->vlan_tag = conn_info->vlan_tag; con->max_conc_seqs_c3 = conn_info->max_conc_seqs_c3; con->flags = conn_info->flags; con->def_q_idx = conn_info->def_q_idx; con->src_mac_addr_hi = (conn_info->src_mac[5] << 8) | conn_info->src_mac[4]; con->src_mac_addr_mid = (conn_info->src_mac[3] << 8) | conn_info->src_mac[2]; con->src_mac_addr_lo = (conn_info->src_mac[1] << 8) | conn_info->src_mac[0]; con->dst_mac_addr_hi = (conn_info->dst_mac[5] << 8) | conn_info->dst_mac[4]; con->dst_mac_addr_mid = (conn_info->dst_mac[3] << 8) | conn_info->dst_mac[2]; con->dst_mac_addr_lo = (conn_info->dst_mac[1] << 8) | conn_info->dst_mac[0]; con->s_id.addr_hi = conn_info->s_id.addr_hi; con->s_id.addr_mid = conn_info->s_id.addr_mid; con->s_id.addr_lo = conn_info->s_id.addr_lo; con->d_id.addr_hi = conn_info->d_id.addr_hi; con->d_id.addr_mid = conn_info->d_id.addr_mid; con->d_id.addr_lo = conn_info->d_id.addr_lo; return qed_sp_fcoe_conn_offload(QED_LEADING_HWFN(cdev), con, QED_SPQ_MODE_EBLOCK, NULL); }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi372100.00%1100.00%
Total372100.00%1100.00%


static int qed_fcoe_destroy_conn(struct qed_dev *cdev, u32 handle, dma_addr_t terminate_params) { struct qed_hash_fcoe_con *hash_con; struct qed_fcoe_conn *con; hash_con = qed_fcoe_get_hash(cdev, handle); if (!hash_con) { DP_NOTICE(cdev, "Failed to find connection for handle %d\n", handle); return -EINVAL; } /* Update the connection with information from the params */ con = hash_con->con; con->terminate_params = terminate_params; return qed_sp_fcoe_conn_destroy(QED_LEADING_HWFN(cdev), con, QED_SPQ_MODE_EBLOCK, NULL); }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi84100.00%1100.00%
Total84100.00%1100.00%


static int qed_fcoe_stats(struct qed_dev *cdev, struct qed_fcoe_stats *stats) { return qed_fcoe_get_stats(QED_LEADING_HWFN(cdev), stats); }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi27100.00%1100.00%
Total27100.00%1100.00%


void qed_get_protocol_stats_fcoe(struct qed_dev *cdev, struct qed_mcp_fcoe_stats *stats) { struct qed_fcoe_stats proto_stats; /* Retrieve FW statistics */ memset(&proto_stats, 0, sizeof(proto_stats)); if (qed_fcoe_stats(cdev, &proto_stats)) { DP_VERBOSE(cdev, QED_MSG_STORAGE, "Failed to collect FCoE statistics\n"); return; } /* Translate FW statistics into struct */ stats->rx_pkts = proto_stats.fcoe_rx_data_pkt_cnt + proto_stats.fcoe_rx_xfer_pkt_cnt + proto_stats.fcoe_rx_other_pkt_cnt; stats->tx_pkts = proto_stats.fcoe_tx_data_pkt_cnt + proto_stats.fcoe_tx_xfer_pkt_cnt + proto_stats.fcoe_tx_other_pkt_cnt; stats->fcs_err = proto_stats.fcoe_silent_drop_pkt_crc_error_cnt; /* Request protocol driver to fill-in the rest */ if (cdev->protocol_ops.fcoe && cdev->ops_cookie) { struct qed_fcoe_cb_ops *ops = cdev->protocol_ops.fcoe; void *cookie = cdev->ops_cookie; if (ops->get_login_failures) stats->login_failure = ops->get_login_failures(cookie); } }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi147100.00%1100.00%
Total147100.00%1100.00%

static const struct qed_fcoe_ops qed_fcoe_ops_pass = { .common = &qed_common_ops_pass, .ll2 = &qed_ll2_ops_pass, .fill_dev_info = &qed_fill_fcoe_dev_info, .start = &qed_fcoe_start, .stop = &qed_fcoe_stop, .register_ops = &qed_register_fcoe_ops, .acquire_conn = &qed_fcoe_acquire_conn, .release_conn = &qed_fcoe_release_conn, .offload_conn = &qed_fcoe_offload_conn, .destroy_conn = &qed_fcoe_destroy_conn, .get_stats = &qed_fcoe_stats, };
const struct qed_fcoe_ops *qed_get_fcoe_ops(void) { return &qed_fcoe_ops_pass; }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi14100.00%1100.00%
Total14100.00%1100.00%

EXPORT_SYMBOL(qed_get_fcoe_ops);
void qed_put_fcoe_ops(void) { }

Contributors

PersonTokensPropCommitsCommitProp
Arun Easi6100.00%1100.00%
Total6100.00%1100.00%

EXPORT_SYMBOL(qed_put_fcoe_ops);

Overall Contributors

PersonTokensPropCommitsCommitProp
Arun Easi5052100.00%1100.00%
Total5052100.00%1100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.