cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bnx2fc_hwi.c (63377B)


      1/* bnx2fc_hwi.c: QLogic Linux FCoE offload driver.
      2 * This file contains the code that low level functions that interact
      3 * with 57712 FCoE firmware.
      4 *
      5 * Copyright (c) 2008-2013 Broadcom Corporation
      6 * Copyright (c) 2014-2016 QLogic Corporation
      7 * Copyright (c) 2016-2017 Cavium Inc.
      8 *
      9 * This program is free software; you can redistribute it and/or modify
     10 * it under the terms of the GNU General Public License as published by
     11 * the Free Software Foundation.
     12 *
     13 * Written by: Bhanu Prakash Gollapudi (bprakash@broadcom.com)
     14 */
     15
     16#include "bnx2fc.h"
     17
     18DECLARE_PER_CPU(struct bnx2fc_percpu_s, bnx2fc_percpu);
     19
     20static void bnx2fc_fastpath_notification(struct bnx2fc_hba *hba,
     21					struct fcoe_kcqe *new_cqe_kcqe);
     22static void bnx2fc_process_ofld_cmpl(struct bnx2fc_hba *hba,
     23					struct fcoe_kcqe *ofld_kcqe);
     24static void bnx2fc_process_enable_conn_cmpl(struct bnx2fc_hba *hba,
     25						struct fcoe_kcqe *ofld_kcqe);
     26static void bnx2fc_init_failure(struct bnx2fc_hba *hba, u32 err_code);
     27static void bnx2fc_process_conn_destroy_cmpl(struct bnx2fc_hba *hba,
     28					struct fcoe_kcqe *destroy_kcqe);
     29
     30int bnx2fc_send_stat_req(struct bnx2fc_hba *hba)
     31{
     32	struct fcoe_kwqe_stat stat_req;
     33	struct kwqe *kwqe_arr[2];
     34	int num_kwqes = 1;
     35	int rc = 0;
     36
     37	memset(&stat_req, 0x00, sizeof(struct fcoe_kwqe_stat));
     38	stat_req.hdr.op_code = FCOE_KWQE_OPCODE_STAT;
     39	stat_req.hdr.flags =
     40		(FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
     41
     42	stat_req.stat_params_addr_lo = (u32) hba->stats_buf_dma;
     43	stat_req.stat_params_addr_hi = (u32) ((u64)hba->stats_buf_dma >> 32);
     44
     45	kwqe_arr[0] = (struct kwqe *) &stat_req;
     46
     47	if (hba->cnic && hba->cnic->submit_kwqes)
     48		rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes);
     49
     50	return rc;
     51}
     52
     53/**
     54 * bnx2fc_send_fw_fcoe_init_msg - initiates initial handshake with FCoE f/w
     55 *
     56 * @hba:	adapter structure pointer
     57 *
     58 * Send down FCoE firmware init KWQEs which initiates the initial handshake
     59 *	with the f/w.
     60 *
     61 */
     62int bnx2fc_send_fw_fcoe_init_msg(struct bnx2fc_hba *hba)
     63{
     64	struct fcoe_kwqe_init1 fcoe_init1;
     65	struct fcoe_kwqe_init2 fcoe_init2;
     66	struct fcoe_kwqe_init3 fcoe_init3;
     67	struct kwqe *kwqe_arr[3];
     68	int num_kwqes = 3;
     69	int rc = 0;
     70
     71	if (!hba->cnic) {
     72		printk(KERN_ERR PFX "hba->cnic NULL during fcoe fw init\n");
     73		return -ENODEV;
     74	}
     75
     76	/* fill init1 KWQE */
     77	memset(&fcoe_init1, 0x00, sizeof(struct fcoe_kwqe_init1));
     78	fcoe_init1.hdr.op_code = FCOE_KWQE_OPCODE_INIT1;
     79	fcoe_init1.hdr.flags = (FCOE_KWQE_LAYER_CODE <<
     80					FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
     81
     82	fcoe_init1.num_tasks = hba->max_tasks;
     83	fcoe_init1.sq_num_wqes = BNX2FC_SQ_WQES_MAX;
     84	fcoe_init1.rq_num_wqes = BNX2FC_RQ_WQES_MAX;
     85	fcoe_init1.rq_buffer_log_size = BNX2FC_RQ_BUF_LOG_SZ;
     86	fcoe_init1.cq_num_wqes = BNX2FC_CQ_WQES_MAX;
     87	fcoe_init1.dummy_buffer_addr_lo = (u32) hba->dummy_buf_dma;
     88	fcoe_init1.dummy_buffer_addr_hi = (u32) ((u64)hba->dummy_buf_dma >> 32);
     89	fcoe_init1.task_list_pbl_addr_lo = (u32) hba->task_ctx_bd_dma;
     90	fcoe_init1.task_list_pbl_addr_hi =
     91				(u32) ((u64) hba->task_ctx_bd_dma >> 32);
     92	fcoe_init1.mtu = BNX2FC_MINI_JUMBO_MTU;
     93
     94	fcoe_init1.flags = (PAGE_SHIFT <<
     95				FCOE_KWQE_INIT1_LOG_PAGE_SIZE_SHIFT);
     96
     97	fcoe_init1.num_sessions_log = BNX2FC_NUM_MAX_SESS_LOG;
     98
     99	/* fill init2 KWQE */
    100	memset(&fcoe_init2, 0x00, sizeof(struct fcoe_kwqe_init2));
    101	fcoe_init2.hdr.op_code = FCOE_KWQE_OPCODE_INIT2;
    102	fcoe_init2.hdr.flags = (FCOE_KWQE_LAYER_CODE <<
    103					FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
    104
    105	fcoe_init2.hsi_major_version = FCOE_HSI_MAJOR_VERSION;
    106	fcoe_init2.hsi_minor_version = FCOE_HSI_MINOR_VERSION;
    107
    108
    109	fcoe_init2.hash_tbl_pbl_addr_lo = (u32) hba->hash_tbl_pbl_dma;
    110	fcoe_init2.hash_tbl_pbl_addr_hi = (u32)
    111					   ((u64) hba->hash_tbl_pbl_dma >> 32);
    112
    113	fcoe_init2.t2_hash_tbl_addr_lo = (u32) hba->t2_hash_tbl_dma;
    114	fcoe_init2.t2_hash_tbl_addr_hi = (u32)
    115					  ((u64) hba->t2_hash_tbl_dma >> 32);
    116
    117	fcoe_init2.t2_ptr_hash_tbl_addr_lo = (u32) hba->t2_hash_tbl_ptr_dma;
    118	fcoe_init2.t2_ptr_hash_tbl_addr_hi = (u32)
    119					((u64) hba->t2_hash_tbl_ptr_dma >> 32);
    120
    121	fcoe_init2.free_list_count = BNX2FC_NUM_MAX_SESS;
    122
    123	/* fill init3 KWQE */
    124	memset(&fcoe_init3, 0x00, sizeof(struct fcoe_kwqe_init3));
    125	fcoe_init3.hdr.op_code = FCOE_KWQE_OPCODE_INIT3;
    126	fcoe_init3.hdr.flags = (FCOE_KWQE_LAYER_CODE <<
    127					FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
    128	fcoe_init3.error_bit_map_lo = 0xffffffff;
    129	fcoe_init3.error_bit_map_hi = 0xffffffff;
    130
    131	/*
    132	 * enable both cached connection and cached tasks
    133	 * 0 = none, 1 = cached connection, 2 = cached tasks, 3 = both
    134	 */
    135	fcoe_init3.perf_config = 3;
    136
    137	kwqe_arr[0] = (struct kwqe *) &fcoe_init1;
    138	kwqe_arr[1] = (struct kwqe *) &fcoe_init2;
    139	kwqe_arr[2] = (struct kwqe *) &fcoe_init3;
    140
    141	if (hba->cnic && hba->cnic->submit_kwqes)
    142		rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes);
    143
    144	return rc;
    145}
    146int bnx2fc_send_fw_fcoe_destroy_msg(struct bnx2fc_hba *hba)
    147{
    148	struct fcoe_kwqe_destroy fcoe_destroy;
    149	struct kwqe *kwqe_arr[2];
    150	int num_kwqes = 1;
    151	int rc = -1;
    152
    153	/* fill destroy KWQE */
    154	memset(&fcoe_destroy, 0x00, sizeof(struct fcoe_kwqe_destroy));
    155	fcoe_destroy.hdr.op_code = FCOE_KWQE_OPCODE_DESTROY;
    156	fcoe_destroy.hdr.flags = (FCOE_KWQE_LAYER_CODE <<
    157					FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
    158	kwqe_arr[0] = (struct kwqe *) &fcoe_destroy;
    159
    160	if (hba->cnic && hba->cnic->submit_kwqes)
    161		rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes);
    162	return rc;
    163}
    164
    165/**
    166 * bnx2fc_send_session_ofld_req - initiates FCoE Session offload process
    167 *
    168 * @port:		port structure pointer
    169 * @tgt:		bnx2fc_rport structure pointer
    170 */
    171int bnx2fc_send_session_ofld_req(struct fcoe_port *port,
    172					struct bnx2fc_rport *tgt)
    173{
    174	struct fc_lport *lport = port->lport;
    175	struct bnx2fc_interface *interface = port->priv;
    176	struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
    177	struct bnx2fc_hba *hba = interface->hba;
    178	struct kwqe *kwqe_arr[4];
    179	struct fcoe_kwqe_conn_offload1 ofld_req1;
    180	struct fcoe_kwqe_conn_offload2 ofld_req2;
    181	struct fcoe_kwqe_conn_offload3 ofld_req3;
    182	struct fcoe_kwqe_conn_offload4 ofld_req4;
    183	struct fc_rport_priv *rdata = tgt->rdata;
    184	struct fc_rport *rport = tgt->rport;
    185	int num_kwqes = 4;
    186	u32 port_id;
    187	int rc = 0;
    188	u16 conn_id;
    189
    190	/* Initialize offload request 1 structure */
    191	memset(&ofld_req1, 0x00, sizeof(struct fcoe_kwqe_conn_offload1));
    192
    193	ofld_req1.hdr.op_code = FCOE_KWQE_OPCODE_OFFLOAD_CONN1;
    194	ofld_req1.hdr.flags =
    195		(FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
    196
    197
    198	conn_id = (u16)tgt->fcoe_conn_id;
    199	ofld_req1.fcoe_conn_id = conn_id;
    200
    201
    202	ofld_req1.sq_addr_lo = (u32) tgt->sq_dma;
    203	ofld_req1.sq_addr_hi = (u32)((u64) tgt->sq_dma >> 32);
    204
    205	ofld_req1.rq_pbl_addr_lo = (u32) tgt->rq_pbl_dma;
    206	ofld_req1.rq_pbl_addr_hi = (u32)((u64) tgt->rq_pbl_dma >> 32);
    207
    208	ofld_req1.rq_first_pbe_addr_lo = (u32) tgt->rq_dma;
    209	ofld_req1.rq_first_pbe_addr_hi =
    210				(u32)((u64) tgt->rq_dma >> 32);
    211
    212	ofld_req1.rq_prod = 0x8000;
    213
    214	/* Initialize offload request 2 structure */
    215	memset(&ofld_req2, 0x00, sizeof(struct fcoe_kwqe_conn_offload2));
    216
    217	ofld_req2.hdr.op_code = FCOE_KWQE_OPCODE_OFFLOAD_CONN2;
    218	ofld_req2.hdr.flags =
    219		(FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
    220
    221	ofld_req2.tx_max_fc_pay_len = rdata->maxframe_size;
    222
    223	ofld_req2.cq_addr_lo = (u32) tgt->cq_dma;
    224	ofld_req2.cq_addr_hi = (u32)((u64)tgt->cq_dma >> 32);
    225
    226	ofld_req2.xferq_addr_lo = (u32) tgt->xferq_dma;
    227	ofld_req2.xferq_addr_hi = (u32)((u64)tgt->xferq_dma >> 32);
    228
    229	ofld_req2.conn_db_addr_lo = (u32)tgt->conn_db_dma;
    230	ofld_req2.conn_db_addr_hi = (u32)((u64)tgt->conn_db_dma >> 32);
    231
    232	/* Initialize offload request 3 structure */
    233	memset(&ofld_req3, 0x00, sizeof(struct fcoe_kwqe_conn_offload3));
    234
    235	ofld_req3.hdr.op_code = FCOE_KWQE_OPCODE_OFFLOAD_CONN3;
    236	ofld_req3.hdr.flags =
    237		(FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
    238
    239	ofld_req3.vlan_tag = interface->vlan_id <<
    240				FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID_SHIFT;
    241	ofld_req3.vlan_tag |= 3 << FCOE_KWQE_CONN_OFFLOAD3_PRIORITY_SHIFT;
    242
    243	port_id = fc_host_port_id(lport->host);
    244	if (port_id == 0) {
    245		BNX2FC_HBA_DBG(lport, "ofld_req: port_id = 0, link down?\n");
    246		return -EINVAL;
    247	}
    248
    249	/*
    250	 * Store s_id of the initiator for further reference. This will
    251	 * be used during disable/destroy during linkdown processing as
    252	 * when the lport is reset, the port_id also is reset to 0
    253	 */
    254	tgt->sid = port_id;
    255	ofld_req3.s_id[0] = (port_id & 0x000000FF);
    256	ofld_req3.s_id[1] = (port_id & 0x0000FF00) >> 8;
    257	ofld_req3.s_id[2] = (port_id & 0x00FF0000) >> 16;
    258
    259	port_id = rport->port_id;
    260	ofld_req3.d_id[0] = (port_id & 0x000000FF);
    261	ofld_req3.d_id[1] = (port_id & 0x0000FF00) >> 8;
    262	ofld_req3.d_id[2] = (port_id & 0x00FF0000) >> 16;
    263
    264	ofld_req3.tx_total_conc_seqs = rdata->max_seq;
    265
    266	ofld_req3.tx_max_conc_seqs_c3 = rdata->max_seq;
    267	ofld_req3.rx_max_fc_pay_len  = lport->mfs;
    268
    269	ofld_req3.rx_total_conc_seqs = BNX2FC_MAX_SEQS;
    270	ofld_req3.rx_max_conc_seqs_c3 = BNX2FC_MAX_SEQS;
    271	ofld_req3.rx_open_seqs_exch_c3 = 1;
    272
    273	ofld_req3.confq_first_pbe_addr_lo = tgt->confq_dma;
    274	ofld_req3.confq_first_pbe_addr_hi = (u32)((u64) tgt->confq_dma >> 32);
    275
    276	/* set mul_n_port_ids supported flag to 0, until it is supported */
    277	ofld_req3.flags = 0;
    278	/*
    279	ofld_req3.flags |= (((lport->send_sp_features & FC_SP_FT_MNA) ? 1:0) <<
    280			    FCOE_KWQE_CONN_OFFLOAD3_B_MUL_N_PORT_IDS_SHIFT);
    281	*/
    282	/* Info from PLOGI response */
    283	ofld_req3.flags |= (((rdata->sp_features & FC_SP_FT_EDTR) ? 1 : 0) <<
    284			     FCOE_KWQE_CONN_OFFLOAD3_B_E_D_TOV_RES_SHIFT);
    285
    286	ofld_req3.flags |= (((rdata->sp_features & FC_SP_FT_SEQC) ? 1 : 0) <<
    287			     FCOE_KWQE_CONN_OFFLOAD3_B_CONT_INCR_SEQ_CNT_SHIFT);
    288
    289	/*
    290	 * Info from PRLI response, this info is used for sequence level error
    291	 * recovery support
    292	 */
    293	if (tgt->dev_type == TYPE_TAPE) {
    294		ofld_req3.flags |= 1 <<
    295				    FCOE_KWQE_CONN_OFFLOAD3_B_CONF_REQ_SHIFT;
    296		ofld_req3.flags |= (((rdata->flags & FC_RP_FLAGS_REC_SUPPORTED)
    297				    ? 1 : 0) <<
    298				    FCOE_KWQE_CONN_OFFLOAD3_B_REC_VALID_SHIFT);
    299	}
    300
    301	/* vlan flag */
    302	ofld_req3.flags |= (interface->vlan_enabled <<
    303			    FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG_SHIFT);
    304
    305	/* C2_VALID and ACK flags are not set as they are not supported */
    306
    307
    308	/* Initialize offload request 4 structure */
    309	memset(&ofld_req4, 0x00, sizeof(struct fcoe_kwqe_conn_offload4));
    310	ofld_req4.hdr.op_code = FCOE_KWQE_OPCODE_OFFLOAD_CONN4;
    311	ofld_req4.hdr.flags =
    312		(FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
    313
    314	ofld_req4.e_d_tov_timer_val = lport->e_d_tov / 20;
    315
    316
    317	ofld_req4.src_mac_addr_lo[0] =  port->data_src_addr[5];
    318							/* local mac */
    319	ofld_req4.src_mac_addr_lo[1] =  port->data_src_addr[4];
    320	ofld_req4.src_mac_addr_mid[0] =  port->data_src_addr[3];
    321	ofld_req4.src_mac_addr_mid[1] =  port->data_src_addr[2];
    322	ofld_req4.src_mac_addr_hi[0] =  port->data_src_addr[1];
    323	ofld_req4.src_mac_addr_hi[1] =  port->data_src_addr[0];
    324	ofld_req4.dst_mac_addr_lo[0] =  ctlr->dest_addr[5];
    325							/* fcf mac */
    326	ofld_req4.dst_mac_addr_lo[1] = ctlr->dest_addr[4];
    327	ofld_req4.dst_mac_addr_mid[0] = ctlr->dest_addr[3];
    328	ofld_req4.dst_mac_addr_mid[1] = ctlr->dest_addr[2];
    329	ofld_req4.dst_mac_addr_hi[0] = ctlr->dest_addr[1];
    330	ofld_req4.dst_mac_addr_hi[1] = ctlr->dest_addr[0];
    331
    332	ofld_req4.lcq_addr_lo = (u32) tgt->lcq_dma;
    333	ofld_req4.lcq_addr_hi = (u32)((u64) tgt->lcq_dma >> 32);
    334
    335	ofld_req4.confq_pbl_base_addr_lo = (u32) tgt->confq_pbl_dma;
    336	ofld_req4.confq_pbl_base_addr_hi =
    337					(u32)((u64) tgt->confq_pbl_dma >> 32);
    338
    339	kwqe_arr[0] = (struct kwqe *) &ofld_req1;
    340	kwqe_arr[1] = (struct kwqe *) &ofld_req2;
    341	kwqe_arr[2] = (struct kwqe *) &ofld_req3;
    342	kwqe_arr[3] = (struct kwqe *) &ofld_req4;
    343
    344	if (hba->cnic && hba->cnic->submit_kwqes)
    345		rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes);
    346
    347	return rc;
    348}
    349
    350/**
    351 * bnx2fc_send_session_enable_req - initiates FCoE Session enablement
    352 *
    353 * @port:		port structure pointer
    354 * @tgt:		bnx2fc_rport structure pointer
    355 */
    356int bnx2fc_send_session_enable_req(struct fcoe_port *port,
    357					struct bnx2fc_rport *tgt)
    358{
    359	struct kwqe *kwqe_arr[2];
    360	struct bnx2fc_interface *interface = port->priv;
    361	struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
    362	struct bnx2fc_hba *hba = interface->hba;
    363	struct fcoe_kwqe_conn_enable_disable enbl_req;
    364	struct fc_lport *lport = port->lport;
    365	struct fc_rport *rport = tgt->rport;
    366	int num_kwqes = 1;
    367	int rc = 0;
    368	u32 port_id;
    369
    370	memset(&enbl_req, 0x00,
    371	       sizeof(struct fcoe_kwqe_conn_enable_disable));
    372	enbl_req.hdr.op_code = FCOE_KWQE_OPCODE_ENABLE_CONN;
    373	enbl_req.hdr.flags =
    374		(FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
    375
    376	enbl_req.src_mac_addr_lo[0] =  port->data_src_addr[5];
    377							/* local mac */
    378	enbl_req.src_mac_addr_lo[1] =  port->data_src_addr[4];
    379	enbl_req.src_mac_addr_mid[0] =  port->data_src_addr[3];
    380	enbl_req.src_mac_addr_mid[1] =  port->data_src_addr[2];
    381	enbl_req.src_mac_addr_hi[0] =  port->data_src_addr[1];
    382	enbl_req.src_mac_addr_hi[1] =  port->data_src_addr[0];
    383	memcpy(tgt->src_addr, port->data_src_addr, ETH_ALEN);
    384
    385	enbl_req.dst_mac_addr_lo[0] =  ctlr->dest_addr[5];
    386	enbl_req.dst_mac_addr_lo[1] =  ctlr->dest_addr[4];
    387	enbl_req.dst_mac_addr_mid[0] = ctlr->dest_addr[3];
    388	enbl_req.dst_mac_addr_mid[1] = ctlr->dest_addr[2];
    389	enbl_req.dst_mac_addr_hi[0] = ctlr->dest_addr[1];
    390	enbl_req.dst_mac_addr_hi[1] = ctlr->dest_addr[0];
    391
    392	port_id = fc_host_port_id(lport->host);
    393	if (port_id != tgt->sid) {
    394		printk(KERN_ERR PFX "WARN: enable_req port_id = 0x%x,"
    395				"sid = 0x%x\n", port_id, tgt->sid);
    396		port_id = tgt->sid;
    397	}
    398	enbl_req.s_id[0] = (port_id & 0x000000FF);
    399	enbl_req.s_id[1] = (port_id & 0x0000FF00) >> 8;
    400	enbl_req.s_id[2] = (port_id & 0x00FF0000) >> 16;
    401
    402	port_id = rport->port_id;
    403	enbl_req.d_id[0] = (port_id & 0x000000FF);
    404	enbl_req.d_id[1] = (port_id & 0x0000FF00) >> 8;
    405	enbl_req.d_id[2] = (port_id & 0x00FF0000) >> 16;
    406	enbl_req.vlan_tag = interface->vlan_id <<
    407				FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID_SHIFT;
    408	enbl_req.vlan_tag |= 3 << FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY_SHIFT;
    409	enbl_req.vlan_flag = interface->vlan_enabled;
    410	enbl_req.context_id = tgt->context_id;
    411	enbl_req.conn_id = tgt->fcoe_conn_id;
    412
    413	kwqe_arr[0] = (struct kwqe *) &enbl_req;
    414
    415	if (hba->cnic && hba->cnic->submit_kwqes)
    416		rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes);
    417	return rc;
    418}
    419
    420/**
    421 * bnx2fc_send_session_disable_req - initiates FCoE Session disable
    422 *
    423 * @port:		port structure pointer
    424 * @tgt:		bnx2fc_rport structure pointer
    425 */
    426int bnx2fc_send_session_disable_req(struct fcoe_port *port,
    427				    struct bnx2fc_rport *tgt)
    428{
    429	struct bnx2fc_interface *interface = port->priv;
    430	struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
    431	struct bnx2fc_hba *hba = interface->hba;
    432	struct fcoe_kwqe_conn_enable_disable disable_req;
    433	struct kwqe *kwqe_arr[2];
    434	struct fc_rport *rport = tgt->rport;
    435	int num_kwqes = 1;
    436	int rc = 0;
    437	u32 port_id;
    438
    439	memset(&disable_req, 0x00,
    440	       sizeof(struct fcoe_kwqe_conn_enable_disable));
    441	disable_req.hdr.op_code = FCOE_KWQE_OPCODE_DISABLE_CONN;
    442	disable_req.hdr.flags =
    443		(FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
    444
    445	disable_req.src_mac_addr_lo[0] =  tgt->src_addr[5];
    446	disable_req.src_mac_addr_lo[1] =  tgt->src_addr[4];
    447	disable_req.src_mac_addr_mid[0] =  tgt->src_addr[3];
    448	disable_req.src_mac_addr_mid[1] =  tgt->src_addr[2];
    449	disable_req.src_mac_addr_hi[0] =  tgt->src_addr[1];
    450	disable_req.src_mac_addr_hi[1] =  tgt->src_addr[0];
    451
    452	disable_req.dst_mac_addr_lo[0] =  ctlr->dest_addr[5];
    453	disable_req.dst_mac_addr_lo[1] =  ctlr->dest_addr[4];
    454	disable_req.dst_mac_addr_mid[0] = ctlr->dest_addr[3];
    455	disable_req.dst_mac_addr_mid[1] = ctlr->dest_addr[2];
    456	disable_req.dst_mac_addr_hi[0] = ctlr->dest_addr[1];
    457	disable_req.dst_mac_addr_hi[1] = ctlr->dest_addr[0];
    458
    459	port_id = tgt->sid;
    460	disable_req.s_id[0] = (port_id & 0x000000FF);
    461	disable_req.s_id[1] = (port_id & 0x0000FF00) >> 8;
    462	disable_req.s_id[2] = (port_id & 0x00FF0000) >> 16;
    463
    464
    465	port_id = rport->port_id;
    466	disable_req.d_id[0] = (port_id & 0x000000FF);
    467	disable_req.d_id[1] = (port_id & 0x0000FF00) >> 8;
    468	disable_req.d_id[2] = (port_id & 0x00FF0000) >> 16;
    469	disable_req.context_id = tgt->context_id;
    470	disable_req.conn_id = tgt->fcoe_conn_id;
    471	disable_req.vlan_tag = interface->vlan_id <<
    472				FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID_SHIFT;
    473	disable_req.vlan_tag |=
    474			3 << FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY_SHIFT;
    475	disable_req.vlan_flag = interface->vlan_enabled;
    476
    477	kwqe_arr[0] = (struct kwqe *) &disable_req;
    478
    479	if (hba->cnic && hba->cnic->submit_kwqes)
    480		rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes);
    481
    482	return rc;
    483}
    484
    485/**
    486 * bnx2fc_send_session_destroy_req - initiates FCoE Session destroy
    487 *
    488 * @hba:		adapter structure pointer
    489 * @tgt:		bnx2fc_rport structure pointer
    490 */
    491int bnx2fc_send_session_destroy_req(struct bnx2fc_hba *hba,
    492					struct bnx2fc_rport *tgt)
    493{
    494	struct fcoe_kwqe_conn_destroy destroy_req;
    495	struct kwqe *kwqe_arr[2];
    496	int num_kwqes = 1;
    497	int rc = 0;
    498
    499	memset(&destroy_req, 0x00, sizeof(struct fcoe_kwqe_conn_destroy));
    500	destroy_req.hdr.op_code = FCOE_KWQE_OPCODE_DESTROY_CONN;
    501	destroy_req.hdr.flags =
    502		(FCOE_KWQE_LAYER_CODE << FCOE_KWQE_HEADER_LAYER_CODE_SHIFT);
    503
    504	destroy_req.context_id = tgt->context_id;
    505	destroy_req.conn_id = tgt->fcoe_conn_id;
    506
    507	kwqe_arr[0] = (struct kwqe *) &destroy_req;
    508
    509	if (hba->cnic && hba->cnic->submit_kwqes)
    510		rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes);
    511
    512	return rc;
    513}
    514
    515static bool is_valid_lport(struct bnx2fc_hba *hba, struct fc_lport *lport)
    516{
    517	struct bnx2fc_lport *blport;
    518
    519	spin_lock_bh(&hba->hba_lock);
    520	list_for_each_entry(blport, &hba->vports, list) {
    521		if (blport->lport == lport) {
    522			spin_unlock_bh(&hba->hba_lock);
    523			return true;
    524		}
    525	}
    526	spin_unlock_bh(&hba->hba_lock);
    527	return false;
    528
    529}
    530
    531
    532static void bnx2fc_unsol_els_work(struct work_struct *work)
    533{
    534	struct bnx2fc_unsol_els *unsol_els;
    535	struct fc_lport *lport;
    536	struct bnx2fc_hba *hba;
    537	struct fc_frame *fp;
    538
    539	unsol_els = container_of(work, struct bnx2fc_unsol_els, unsol_els_work);
    540	lport = unsol_els->lport;
    541	fp = unsol_els->fp;
    542	hba = unsol_els->hba;
    543	if (is_valid_lport(hba, lport))
    544		fc_exch_recv(lport, fp);
    545	kfree(unsol_els);
    546}
    547
    548void bnx2fc_process_l2_frame_compl(struct bnx2fc_rport *tgt,
    549				   unsigned char *buf,
    550				   u32 frame_len, u16 l2_oxid)
    551{
    552	struct fcoe_port *port = tgt->port;
    553	struct fc_lport *lport = port->lport;
    554	struct bnx2fc_interface *interface = port->priv;
    555	struct bnx2fc_unsol_els *unsol_els;
    556	struct fc_frame_header *fh;
    557	struct fc_frame *fp;
    558	struct sk_buff *skb;
    559	u32 payload_len;
    560	u32 crc;
    561	u8 op;
    562
    563
    564	unsol_els = kzalloc(sizeof(*unsol_els), GFP_ATOMIC);
    565	if (!unsol_els) {
    566		BNX2FC_TGT_DBG(tgt, "Unable to allocate unsol_work\n");
    567		return;
    568	}
    569
    570	BNX2FC_TGT_DBG(tgt, "l2_frame_compl l2_oxid = 0x%x, frame_len = %d\n",
    571		l2_oxid, frame_len);
    572
    573	payload_len = frame_len - sizeof(struct fc_frame_header);
    574
    575	fp = fc_frame_alloc(lport, payload_len);
    576	if (!fp) {
    577		printk(KERN_ERR PFX "fc_frame_alloc failure\n");
    578		kfree(unsol_els);
    579		return;
    580	}
    581
    582	fh = (struct fc_frame_header *) fc_frame_header_get(fp);
    583	/* Copy FC Frame header and payload into the frame */
    584	memcpy(fh, buf, frame_len);
    585
    586	if (l2_oxid != FC_XID_UNKNOWN)
    587		fh->fh_ox_id = htons(l2_oxid);
    588
    589	skb = fp_skb(fp);
    590
    591	if ((fh->fh_r_ctl == FC_RCTL_ELS_REQ) ||
    592	    (fh->fh_r_ctl == FC_RCTL_ELS_REP)) {
    593
    594		if (fh->fh_type == FC_TYPE_ELS) {
    595			op = fc_frame_payload_op(fp);
    596			if ((op == ELS_TEST) ||	(op == ELS_ESTC) ||
    597			    (op == ELS_FAN) || (op == ELS_CSU)) {
    598				/*
    599				 * No need to reply for these
    600				 * ELS requests
    601				 */
    602				printk(KERN_ERR PFX "dropping ELS 0x%x\n", op);
    603				kfree_skb(skb);
    604				kfree(unsol_els);
    605				return;
    606			}
    607		}
    608		crc = fcoe_fc_crc(fp);
    609		fc_frame_init(fp);
    610		fr_dev(fp) = lport;
    611		fr_sof(fp) = FC_SOF_I3;
    612		fr_eof(fp) = FC_EOF_T;
    613		fr_crc(fp) = cpu_to_le32(~crc);
    614		unsol_els->lport = lport;
    615		unsol_els->hba = interface->hba;
    616		unsol_els->fp = fp;
    617		INIT_WORK(&unsol_els->unsol_els_work, bnx2fc_unsol_els_work);
    618		queue_work(bnx2fc_wq, &unsol_els->unsol_els_work);
    619	} else {
    620		BNX2FC_HBA_DBG(lport, "fh_r_ctl = 0x%x\n", fh->fh_r_ctl);
    621		kfree_skb(skb);
    622		kfree(unsol_els);
    623	}
    624}
    625
    626static void bnx2fc_process_unsol_compl(struct bnx2fc_rport *tgt, u16 wqe)
    627{
    628	u8 num_rq;
    629	struct fcoe_err_report_entry *err_entry;
    630	unsigned char *rq_data;
    631	unsigned char *buf = NULL, *buf1;
    632	int i;
    633	u16 xid;
    634	u32 frame_len, len;
    635	struct bnx2fc_cmd *io_req = NULL;
    636	struct bnx2fc_interface *interface = tgt->port->priv;
    637	struct bnx2fc_hba *hba = interface->hba;
    638	int rc = 0;
    639	u64 err_warn_bit_map;
    640	u8 err_warn = 0xff;
    641
    642
    643	BNX2FC_TGT_DBG(tgt, "Entered UNSOL COMPLETION wqe = 0x%x\n", wqe);
    644	switch (wqe & FCOE_UNSOLICITED_CQE_SUBTYPE) {
    645	case FCOE_UNSOLICITED_FRAME_CQE_TYPE:
    646		frame_len = (wqe & FCOE_UNSOLICITED_CQE_PKT_LEN) >>
    647			     FCOE_UNSOLICITED_CQE_PKT_LEN_SHIFT;
    648
    649		num_rq = (frame_len + BNX2FC_RQ_BUF_SZ - 1) / BNX2FC_RQ_BUF_SZ;
    650
    651		spin_lock_bh(&tgt->tgt_lock);
    652		rq_data = (unsigned char *)bnx2fc_get_next_rqe(tgt, num_rq);
    653		spin_unlock_bh(&tgt->tgt_lock);
    654
    655		if (rq_data) {
    656			buf = rq_data;
    657		} else {
    658			buf1 = buf = kmalloc((num_rq * BNX2FC_RQ_BUF_SZ),
    659					      GFP_ATOMIC);
    660
    661			if (!buf1) {
    662				BNX2FC_TGT_DBG(tgt, "Memory alloc failure\n");
    663				break;
    664			}
    665
    666			for (i = 0; i < num_rq; i++) {
    667				spin_lock_bh(&tgt->tgt_lock);
    668				rq_data = (unsigned char *)
    669					   bnx2fc_get_next_rqe(tgt, 1);
    670				spin_unlock_bh(&tgt->tgt_lock);
    671				len = BNX2FC_RQ_BUF_SZ;
    672				memcpy(buf1, rq_data, len);
    673				buf1 += len;
    674			}
    675		}
    676		bnx2fc_process_l2_frame_compl(tgt, buf, frame_len,
    677					      FC_XID_UNKNOWN);
    678
    679		if (buf != rq_data)
    680			kfree(buf);
    681		spin_lock_bh(&tgt->tgt_lock);
    682		bnx2fc_return_rqe(tgt, num_rq);
    683		spin_unlock_bh(&tgt->tgt_lock);
    684		break;
    685
    686	case FCOE_ERROR_DETECTION_CQE_TYPE:
    687		/*
    688		 * In case of error reporting CQE a single RQ entry
    689		 * is consumed.
    690		 */
    691		spin_lock_bh(&tgt->tgt_lock);
    692		num_rq = 1;
    693		err_entry = (struct fcoe_err_report_entry *)
    694			     bnx2fc_get_next_rqe(tgt, 1);
    695		xid = err_entry->fc_hdr.ox_id;
    696		BNX2FC_TGT_DBG(tgt, "Unsol Error Frame OX_ID = 0x%x\n", xid);
    697		BNX2FC_TGT_DBG(tgt, "err_warn_bitmap = %08x:%08x\n",
    698			err_entry->data.err_warn_bitmap_hi,
    699			err_entry->data.err_warn_bitmap_lo);
    700		BNX2FC_TGT_DBG(tgt, "buf_offsets - tx = 0x%x, rx = 0x%x\n",
    701			err_entry->data.tx_buf_off, err_entry->data.rx_buf_off);
    702
    703		if (xid > hba->max_xid) {
    704			BNX2FC_TGT_DBG(tgt, "xid(0x%x) out of FW range\n",
    705				   xid);
    706			goto ret_err_rqe;
    707		}
    708
    709
    710		io_req = (struct bnx2fc_cmd *)hba->cmd_mgr->cmds[xid];
    711		if (!io_req)
    712			goto ret_err_rqe;
    713
    714		if (io_req->cmd_type != BNX2FC_SCSI_CMD) {
    715			printk(KERN_ERR PFX "err_warn: Not a SCSI cmd\n");
    716			goto ret_err_rqe;
    717		}
    718
    719		if (test_and_clear_bit(BNX2FC_FLAG_IO_CLEANUP,
    720				       &io_req->req_flags)) {
    721			BNX2FC_IO_DBG(io_req, "unsol_err: cleanup in "
    722					    "progress.. ignore unsol err\n");
    723			goto ret_err_rqe;
    724		}
    725
    726		err_warn_bit_map = (u64)
    727			((u64)err_entry->data.err_warn_bitmap_hi << 32) |
    728			(u64)err_entry->data.err_warn_bitmap_lo;
    729		for (i = 0; i < BNX2FC_NUM_ERR_BITS; i++) {
    730			if (err_warn_bit_map & (u64)((u64)1 << i)) {
    731				err_warn = i;
    732				break;
    733			}
    734		}
    735
    736		/*
    737		 * If ABTS is already in progress, and FW error is
    738		 * received after that, do not cancel the timeout_work
    739		 * and let the error recovery continue by explicitly
    740		 * logging out the target, when the ABTS eventually
    741		 * times out.
    742		 */
    743		if (test_bit(BNX2FC_FLAG_ISSUE_ABTS, &io_req->req_flags)) {
    744			printk(KERN_ERR PFX "err_warn: io_req (0x%x) already "
    745					    "in ABTS processing\n", xid);
    746			goto ret_err_rqe;
    747		}
    748		BNX2FC_TGT_DBG(tgt, "err = 0x%x\n", err_warn);
    749		if (tgt->dev_type != TYPE_TAPE)
    750			goto skip_rec;
    751		switch (err_warn) {
    752		case FCOE_ERROR_CODE_REC_TOV_TIMER_EXPIRATION:
    753		case FCOE_ERROR_CODE_DATA_OOO_RO:
    754		case FCOE_ERROR_CODE_COMMON_INCORRECT_SEQ_CNT:
    755		case FCOE_ERROR_CODE_DATA_SOFI3_SEQ_ACTIVE_SET:
    756		case FCOE_ERROR_CODE_FCP_RSP_OPENED_SEQ:
    757		case FCOE_ERROR_CODE_DATA_SOFN_SEQ_ACTIVE_RESET:
    758			BNX2FC_TGT_DBG(tgt, "REC TOV popped for xid - 0x%x\n",
    759				   xid);
    760			memcpy(&io_req->err_entry, err_entry,
    761			       sizeof(struct fcoe_err_report_entry));
    762			if (!test_bit(BNX2FC_FLAG_SRR_SENT,
    763				      &io_req->req_flags)) {
    764				spin_unlock_bh(&tgt->tgt_lock);
    765				rc = bnx2fc_send_rec(io_req);
    766				spin_lock_bh(&tgt->tgt_lock);
    767
    768				if (rc)
    769					goto skip_rec;
    770			} else
    771				printk(KERN_ERR PFX "SRR in progress\n");
    772			goto ret_err_rqe;
    773		default:
    774			break;
    775		}
    776
    777skip_rec:
    778		set_bit(BNX2FC_FLAG_ISSUE_ABTS, &io_req->req_flags);
    779		/*
    780		 * Cancel the timeout_work, as we received IO
    781		 * completion with FW error.
    782		 */
    783		if (cancel_delayed_work(&io_req->timeout_work))
    784			kref_put(&io_req->refcount, bnx2fc_cmd_release);
    785
    786		rc = bnx2fc_initiate_abts(io_req);
    787		if (rc != SUCCESS) {
    788			printk(KERN_ERR PFX "err_warn: initiate_abts "
    789				"failed xid = 0x%x. issue cleanup\n",
    790				io_req->xid);
    791			bnx2fc_initiate_cleanup(io_req);
    792		}
    793ret_err_rqe:
    794		bnx2fc_return_rqe(tgt, 1);
    795		spin_unlock_bh(&tgt->tgt_lock);
    796		break;
    797
    798	case FCOE_WARNING_DETECTION_CQE_TYPE:
    799		/*
    800		 *In case of warning reporting CQE a single RQ entry
    801		 * is consumes.
    802		 */
    803		spin_lock_bh(&tgt->tgt_lock);
    804		num_rq = 1;
    805		err_entry = (struct fcoe_err_report_entry *)
    806			     bnx2fc_get_next_rqe(tgt, 1);
    807		xid = cpu_to_be16(err_entry->fc_hdr.ox_id);
    808		BNX2FC_TGT_DBG(tgt, "Unsol Warning Frame OX_ID = 0x%x\n", xid);
    809		BNX2FC_TGT_DBG(tgt, "err_warn_bitmap = %08x:%08x",
    810			err_entry->data.err_warn_bitmap_hi,
    811			err_entry->data.err_warn_bitmap_lo);
    812		BNX2FC_TGT_DBG(tgt, "buf_offsets - tx = 0x%x, rx = 0x%x",
    813			err_entry->data.tx_buf_off, err_entry->data.rx_buf_off);
    814
    815		if (xid > hba->max_xid) {
    816			BNX2FC_TGT_DBG(tgt, "xid(0x%x) out of FW range\n", xid);
    817			goto ret_warn_rqe;
    818		}
    819
    820		err_warn_bit_map = (u64)
    821			((u64)err_entry->data.err_warn_bitmap_hi << 32) |
    822			(u64)err_entry->data.err_warn_bitmap_lo;
    823		for (i = 0; i < BNX2FC_NUM_ERR_BITS; i++) {
    824			if (err_warn_bit_map & ((u64)1 << i)) {
    825				err_warn = i;
    826				break;
    827			}
    828		}
    829		BNX2FC_TGT_DBG(tgt, "warn = 0x%x\n", err_warn);
    830
    831		io_req = (struct bnx2fc_cmd *)hba->cmd_mgr->cmds[xid];
    832		if (!io_req)
    833			goto ret_warn_rqe;
    834
    835		if (io_req->cmd_type != BNX2FC_SCSI_CMD) {
    836			printk(KERN_ERR PFX "err_warn: Not a SCSI cmd\n");
    837			goto ret_warn_rqe;
    838		}
    839
    840		memcpy(&io_req->err_entry, err_entry,
    841		       sizeof(struct fcoe_err_report_entry));
    842
    843		if (err_warn == FCOE_ERROR_CODE_REC_TOV_TIMER_EXPIRATION)
    844			/* REC_TOV is not a warning code */
    845			BUG_ON(1);
    846		else
    847			BNX2FC_TGT_DBG(tgt, "Unsolicited warning\n");
    848ret_warn_rqe:
    849		bnx2fc_return_rqe(tgt, 1);
    850		spin_unlock_bh(&tgt->tgt_lock);
    851		break;
    852
    853	default:
    854		printk(KERN_ERR PFX "Unsol Compl: Invalid CQE Subtype\n");
    855		break;
    856	}
    857}
    858
    859void bnx2fc_process_cq_compl(struct bnx2fc_rport *tgt, u16 wqe,
    860			     unsigned char *rq_data, u8 num_rq,
    861			     struct fcoe_task_ctx_entry *task)
    862{
    863	struct fcoe_port *port = tgt->port;
    864	struct bnx2fc_interface *interface = port->priv;
    865	struct bnx2fc_hba *hba = interface->hba;
    866	struct bnx2fc_cmd *io_req;
    867
    868	u16 xid;
    869	u8  cmd_type;
    870	u8 rx_state = 0;
    871
    872	spin_lock_bh(&tgt->tgt_lock);
    873
    874	xid = wqe & FCOE_PEND_WQ_CQE_TASK_ID;
    875	io_req = (struct bnx2fc_cmd *)hba->cmd_mgr->cmds[xid];
    876
    877	if (io_req == NULL) {
    878		printk(KERN_ERR PFX "ERROR? cq_compl - io_req is NULL\n");
    879		spin_unlock_bh(&tgt->tgt_lock);
    880		return;
    881	}
    882
    883	/* Timestamp IO completion time */
    884	cmd_type = io_req->cmd_type;
    885
    886	rx_state = ((task->rxwr_txrd.var_ctx.rx_flags &
    887		    FCOE_TCE_RX_WR_TX_RD_VAR_RX_STATE) >>
    888		    FCOE_TCE_RX_WR_TX_RD_VAR_RX_STATE_SHIFT);
    889
    890	/* Process other IO completion types */
    891	switch (cmd_type) {
    892	case BNX2FC_SCSI_CMD:
    893		if (rx_state == FCOE_TASK_RX_STATE_COMPLETED) {
    894			bnx2fc_process_scsi_cmd_compl(io_req, task, num_rq,
    895						      rq_data);
    896			spin_unlock_bh(&tgt->tgt_lock);
    897			return;
    898		}
    899
    900		if (rx_state == FCOE_TASK_RX_STATE_ABTS_COMPLETED)
    901			bnx2fc_process_abts_compl(io_req, task, num_rq);
    902		else if (rx_state ==
    903			 FCOE_TASK_RX_STATE_EXCHANGE_CLEANUP_COMPLETED)
    904			bnx2fc_process_cleanup_compl(io_req, task, num_rq);
    905		else
    906			printk(KERN_ERR PFX "Invalid rx state - %d\n",
    907				rx_state);
    908		break;
    909
    910	case BNX2FC_TASK_MGMT_CMD:
    911		BNX2FC_IO_DBG(io_req, "Processing TM complete\n");
    912		bnx2fc_process_tm_compl(io_req, task, num_rq, rq_data);
    913		break;
    914
    915	case BNX2FC_ABTS:
    916		/*
    917		 * ABTS request received by firmware. ABTS response
    918		 * will be delivered to the task belonging to the IO
    919		 * that was aborted
    920		 */
    921		BNX2FC_IO_DBG(io_req, "cq_compl- ABTS sent out by fw\n");
    922		kref_put(&io_req->refcount, bnx2fc_cmd_release);
    923		break;
    924
    925	case BNX2FC_ELS:
    926		if (rx_state == FCOE_TASK_RX_STATE_COMPLETED)
    927			bnx2fc_process_els_compl(io_req, task, num_rq);
    928		else if (rx_state == FCOE_TASK_RX_STATE_ABTS_COMPLETED)
    929			bnx2fc_process_abts_compl(io_req, task, num_rq);
    930		else if (rx_state ==
    931			 FCOE_TASK_RX_STATE_EXCHANGE_CLEANUP_COMPLETED)
    932			bnx2fc_process_cleanup_compl(io_req, task, num_rq);
    933		else
    934			printk(KERN_ERR PFX "Invalid rx state =  %d\n",
    935				rx_state);
    936		break;
    937
    938	case BNX2FC_CLEANUP:
    939		BNX2FC_IO_DBG(io_req, "cq_compl- cleanup resp rcvd\n");
    940		kref_put(&io_req->refcount, bnx2fc_cmd_release);
    941		break;
    942
    943	case BNX2FC_SEQ_CLEANUP:
    944		BNX2FC_IO_DBG(io_req, "cq_compl(0x%x) - seq cleanup resp\n",
    945			      io_req->xid);
    946		bnx2fc_process_seq_cleanup_compl(io_req, task, rx_state);
    947		kref_put(&io_req->refcount, bnx2fc_cmd_release);
    948		break;
    949
    950	default:
    951		printk(KERN_ERR PFX "Invalid cmd_type %d\n", cmd_type);
    952		break;
    953	}
    954	spin_unlock_bh(&tgt->tgt_lock);
    955}
    956
    957void bnx2fc_arm_cq(struct bnx2fc_rport *tgt)
    958{
    959	struct b577xx_fcoe_rx_doorbell *rx_db = &tgt->rx_db;
    960	u32 msg;
    961
    962	wmb();
    963	rx_db->doorbell_cq_cons = tgt->cq_cons_idx | (tgt->cq_curr_toggle_bit <<
    964			FCOE_CQE_TOGGLE_BIT_SHIFT);
    965	msg = *((u32 *)rx_db);
    966	writel(cpu_to_le32(msg), tgt->ctx_base);
    967
    968}
    969
    970static struct bnx2fc_work *bnx2fc_alloc_work(struct bnx2fc_rport *tgt, u16 wqe,
    971					     unsigned char *rq_data, u8 num_rq,
    972					     struct fcoe_task_ctx_entry *task)
    973{
    974	struct bnx2fc_work *work;
    975	work = kzalloc(sizeof(struct bnx2fc_work), GFP_ATOMIC);
    976	if (!work)
    977		return NULL;
    978
    979	INIT_LIST_HEAD(&work->list);
    980	work->tgt = tgt;
    981	work->wqe = wqe;
    982	work->num_rq = num_rq;
    983	work->task = task;
    984	if (rq_data)
    985		memcpy(work->rq_data, rq_data, BNX2FC_RQ_BUF_SZ);
    986
    987	return work;
    988}
    989
    990/* Pending work request completion */
    991static bool bnx2fc_pending_work(struct bnx2fc_rport *tgt, unsigned int wqe)
    992{
    993	unsigned int cpu = wqe % num_possible_cpus();
    994	struct bnx2fc_percpu_s *fps;
    995	struct bnx2fc_work *work;
    996	struct fcoe_task_ctx_entry *task;
    997	struct fcoe_task_ctx_entry *task_page;
    998	struct fcoe_port *port = tgt->port;
    999	struct bnx2fc_interface *interface = port->priv;
   1000	struct bnx2fc_hba *hba = interface->hba;
   1001	unsigned char *rq_data = NULL;
   1002	unsigned char rq_data_buff[BNX2FC_RQ_BUF_SZ];
   1003	int task_idx, index;
   1004	u16 xid;
   1005	u8 num_rq;
   1006	int i;
   1007
   1008	xid = wqe & FCOE_PEND_WQ_CQE_TASK_ID;
   1009	if (xid >= hba->max_tasks) {
   1010		pr_err(PFX "ERROR:xid out of range\n");
   1011		return false;
   1012	}
   1013
   1014	task_idx = xid / BNX2FC_TASKS_PER_PAGE;
   1015	index = xid % BNX2FC_TASKS_PER_PAGE;
   1016	task_page = (struct fcoe_task_ctx_entry *)hba->task_ctx[task_idx];
   1017	task = &task_page[index];
   1018
   1019	num_rq = ((task->rxwr_txrd.var_ctx.rx_flags &
   1020		   FCOE_TCE_RX_WR_TX_RD_VAR_NUM_RQ_WQE) >>
   1021		  FCOE_TCE_RX_WR_TX_RD_VAR_NUM_RQ_WQE_SHIFT);
   1022
   1023	memset(rq_data_buff, 0, BNX2FC_RQ_BUF_SZ);
   1024
   1025	if (!num_rq)
   1026		goto num_rq_zero;
   1027
   1028	rq_data = bnx2fc_get_next_rqe(tgt, 1);
   1029
   1030	if (num_rq > 1) {
   1031		/* We do not need extra sense data */
   1032		for (i = 1; i < num_rq; i++)
   1033			bnx2fc_get_next_rqe(tgt, 1);
   1034	}
   1035
   1036	if (rq_data)
   1037		memcpy(rq_data_buff, rq_data, BNX2FC_RQ_BUF_SZ);
   1038
   1039	/* return RQ entries */
   1040	for (i = 0; i < num_rq; i++)
   1041		bnx2fc_return_rqe(tgt, 1);
   1042
   1043num_rq_zero:
   1044
   1045	fps = &per_cpu(bnx2fc_percpu, cpu);
   1046	spin_lock_bh(&fps->fp_work_lock);
   1047	if (fps->iothread) {
   1048		work = bnx2fc_alloc_work(tgt, wqe, rq_data_buff,
   1049					 num_rq, task);
   1050		if (work) {
   1051			list_add_tail(&work->list, &fps->work_list);
   1052			wake_up_process(fps->iothread);
   1053			spin_unlock_bh(&fps->fp_work_lock);
   1054			return true;
   1055		}
   1056	}
   1057	spin_unlock_bh(&fps->fp_work_lock);
   1058	bnx2fc_process_cq_compl(tgt, wqe,
   1059				rq_data_buff, num_rq, task);
   1060
   1061	return true;
   1062}
   1063
   1064int bnx2fc_process_new_cqes(struct bnx2fc_rport *tgt)
   1065{
   1066	struct fcoe_cqe *cq;
   1067	u32 cq_cons;
   1068	struct fcoe_cqe *cqe;
   1069	u32 num_free_sqes = 0;
   1070	u32 num_cqes = 0;
   1071	u16 wqe;
   1072
   1073	/*
   1074	 * cq_lock is a low contention lock used to protect
   1075	 * the CQ data structure from being freed up during
   1076	 * the upload operation
   1077	 */
   1078	spin_lock_bh(&tgt->cq_lock);
   1079
   1080	if (!tgt->cq) {
   1081		printk(KERN_ERR PFX "process_new_cqes: cq is NULL\n");
   1082		spin_unlock_bh(&tgt->cq_lock);
   1083		return 0;
   1084	}
   1085	cq = tgt->cq;
   1086	cq_cons = tgt->cq_cons_idx;
   1087	cqe = &cq[cq_cons];
   1088
   1089	while (((wqe = cqe->wqe) & FCOE_CQE_TOGGLE_BIT) ==
   1090	       (tgt->cq_curr_toggle_bit <<
   1091	       FCOE_CQE_TOGGLE_BIT_SHIFT)) {
   1092
   1093		/* new entry on the cq */
   1094		if (wqe & FCOE_CQE_CQE_TYPE) {
   1095			/* Unsolicited event notification */
   1096			bnx2fc_process_unsol_compl(tgt, wqe);
   1097		} else {
   1098			if (bnx2fc_pending_work(tgt, wqe))
   1099				num_free_sqes++;
   1100		}
   1101		cqe++;
   1102		tgt->cq_cons_idx++;
   1103		num_cqes++;
   1104
   1105		if (tgt->cq_cons_idx == BNX2FC_CQ_WQES_MAX) {
   1106			tgt->cq_cons_idx = 0;
   1107			cqe = cq;
   1108			tgt->cq_curr_toggle_bit =
   1109				1 - tgt->cq_curr_toggle_bit;
   1110		}
   1111	}
   1112	if (num_cqes) {
   1113		/* Arm CQ only if doorbell is mapped */
   1114		if (tgt->ctx_base)
   1115			bnx2fc_arm_cq(tgt);
   1116		atomic_add(num_free_sqes, &tgt->free_sqes);
   1117	}
   1118	spin_unlock_bh(&tgt->cq_lock);
   1119	return 0;
   1120}
   1121
   1122/**
   1123 * bnx2fc_fastpath_notification - process global event queue (KCQ)
   1124 *
   1125 * @hba:		adapter structure pointer
   1126 * @new_cqe_kcqe:	pointer to newly DMA'd KCQ entry
   1127 *
   1128 * Fast path event notification handler
   1129 */
   1130static void bnx2fc_fastpath_notification(struct bnx2fc_hba *hba,
   1131					struct fcoe_kcqe *new_cqe_kcqe)
   1132{
   1133	u32 conn_id = new_cqe_kcqe->fcoe_conn_id;
   1134	struct bnx2fc_rport *tgt = hba->tgt_ofld_list[conn_id];
   1135
   1136	if (!tgt) {
   1137		printk(KERN_ERR PFX "conn_id 0x%x not valid\n", conn_id);
   1138		return;
   1139	}
   1140
   1141	bnx2fc_process_new_cqes(tgt);
   1142}
   1143
   1144/**
   1145 * bnx2fc_process_ofld_cmpl - process FCoE session offload completion
   1146 *
   1147 * @hba:	adapter structure pointer
   1148 * @ofld_kcqe:	connection offload kcqe pointer
   1149 *
   1150 * handle session offload completion, enable the session if offload is
   1151 * successful.
   1152 */
   1153static void bnx2fc_process_ofld_cmpl(struct bnx2fc_hba *hba,
   1154					struct fcoe_kcqe *ofld_kcqe)
   1155{
   1156	struct bnx2fc_rport		*tgt;
   1157	struct bnx2fc_interface		*interface;
   1158	u32				conn_id;
   1159	u32				context_id;
   1160
   1161	conn_id = ofld_kcqe->fcoe_conn_id;
   1162	context_id = ofld_kcqe->fcoe_conn_context_id;
   1163	tgt = hba->tgt_ofld_list[conn_id];
   1164	if (!tgt) {
   1165		printk(KERN_ALERT PFX "ERROR:ofld_cmpl: No pending ofld req\n");
   1166		return;
   1167	}
   1168	BNX2FC_TGT_DBG(tgt, "Entered ofld compl - context_id = 0x%x\n",
   1169		ofld_kcqe->fcoe_conn_context_id);
   1170	interface = tgt->port->priv;
   1171	if (hba != interface->hba) {
   1172		printk(KERN_ERR PFX "ERROR:ofld_cmpl: HBA mismatch\n");
   1173		goto ofld_cmpl_err;
   1174	}
   1175	/*
   1176	 * cnic has allocated a context_id for this session; use this
   1177	 * while enabling the session.
   1178	 */
   1179	tgt->context_id = context_id;
   1180	if (ofld_kcqe->completion_status) {
   1181		if (ofld_kcqe->completion_status ==
   1182				FCOE_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE) {
   1183			printk(KERN_ERR PFX "unable to allocate FCoE context "
   1184				"resources\n");
   1185			set_bit(BNX2FC_FLAG_CTX_ALLOC_FAILURE, &tgt->flags);
   1186		}
   1187	} else {
   1188		/* FW offload request successfully completed */
   1189		set_bit(BNX2FC_FLAG_OFFLOADED, &tgt->flags);
   1190	}
   1191ofld_cmpl_err:
   1192	set_bit(BNX2FC_FLAG_OFLD_REQ_CMPL, &tgt->flags);
   1193	wake_up_interruptible(&tgt->ofld_wait);
   1194}
   1195
   1196/**
   1197 * bnx2fc_process_enable_conn_cmpl - process FCoE session enable completion
   1198 *
   1199 * @hba:	adapter structure pointer
   1200 * @ofld_kcqe:	connection offload kcqe pointer
   1201 *
   1202 * handle session enable completion, mark the rport as ready
   1203 */
   1204
   1205static void bnx2fc_process_enable_conn_cmpl(struct bnx2fc_hba *hba,
   1206						struct fcoe_kcqe *ofld_kcqe)
   1207{
   1208	struct bnx2fc_rport		*tgt;
   1209	struct bnx2fc_interface		*interface;
   1210	u32				conn_id;
   1211	u32				context_id;
   1212
   1213	context_id = ofld_kcqe->fcoe_conn_context_id;
   1214	conn_id = ofld_kcqe->fcoe_conn_id;
   1215	tgt = hba->tgt_ofld_list[conn_id];
   1216	if (!tgt) {
   1217		printk(KERN_ERR PFX "ERROR:enbl_cmpl: No pending ofld req\n");
   1218		return;
   1219	}
   1220
   1221	BNX2FC_TGT_DBG(tgt, "Enable compl - context_id = 0x%x\n",
   1222		ofld_kcqe->fcoe_conn_context_id);
   1223
   1224	/*
   1225	 * context_id should be the same for this target during offload
   1226	 * and enable
   1227	 */
   1228	if (tgt->context_id != context_id) {
   1229		printk(KERN_ERR PFX "context id mismatch\n");
   1230		return;
   1231	}
   1232	interface = tgt->port->priv;
   1233	if (hba != interface->hba) {
   1234		printk(KERN_ERR PFX "bnx2fc-enbl_cmpl: HBA mismatch\n");
   1235		goto enbl_cmpl_err;
   1236	}
   1237	if (!ofld_kcqe->completion_status)
   1238		/* enable successful - rport ready for issuing IOs */
   1239		set_bit(BNX2FC_FLAG_ENABLED, &tgt->flags);
   1240
   1241enbl_cmpl_err:
   1242	set_bit(BNX2FC_FLAG_OFLD_REQ_CMPL, &tgt->flags);
   1243	wake_up_interruptible(&tgt->ofld_wait);
   1244}
   1245
   1246static void bnx2fc_process_conn_disable_cmpl(struct bnx2fc_hba *hba,
   1247					struct fcoe_kcqe *disable_kcqe)
   1248{
   1249
   1250	struct bnx2fc_rport		*tgt;
   1251	u32				conn_id;
   1252
   1253	conn_id = disable_kcqe->fcoe_conn_id;
   1254	tgt = hba->tgt_ofld_list[conn_id];
   1255	if (!tgt) {
   1256		printk(KERN_ERR PFX "ERROR: disable_cmpl: No disable req\n");
   1257		return;
   1258	}
   1259
   1260	BNX2FC_TGT_DBG(tgt, PFX "disable_cmpl: conn_id %d\n", conn_id);
   1261
   1262	if (disable_kcqe->completion_status) {
   1263		printk(KERN_ERR PFX "Disable failed with cmpl status %d\n",
   1264			disable_kcqe->completion_status);
   1265		set_bit(BNX2FC_FLAG_DISABLE_FAILED, &tgt->flags);
   1266		set_bit(BNX2FC_FLAG_UPLD_REQ_COMPL, &tgt->flags);
   1267		wake_up_interruptible(&tgt->upld_wait);
   1268	} else {
   1269		/* disable successful */
   1270		BNX2FC_TGT_DBG(tgt, "disable successful\n");
   1271		clear_bit(BNX2FC_FLAG_OFFLOADED, &tgt->flags);
   1272		clear_bit(BNX2FC_FLAG_ENABLED, &tgt->flags);
   1273		set_bit(BNX2FC_FLAG_DISABLED, &tgt->flags);
   1274		set_bit(BNX2FC_FLAG_UPLD_REQ_COMPL, &tgt->flags);
   1275		wake_up_interruptible(&tgt->upld_wait);
   1276	}
   1277}
   1278
   1279static void bnx2fc_process_conn_destroy_cmpl(struct bnx2fc_hba *hba,
   1280					struct fcoe_kcqe *destroy_kcqe)
   1281{
   1282	struct bnx2fc_rport		*tgt;
   1283	u32				conn_id;
   1284
   1285	conn_id = destroy_kcqe->fcoe_conn_id;
   1286	tgt = hba->tgt_ofld_list[conn_id];
   1287	if (!tgt) {
   1288		printk(KERN_ERR PFX "destroy_cmpl: No destroy req\n");
   1289		return;
   1290	}
   1291
   1292	BNX2FC_TGT_DBG(tgt, "destroy_cmpl: conn_id %d\n", conn_id);
   1293
   1294	if (destroy_kcqe->completion_status) {
   1295		printk(KERN_ERR PFX "Destroy conn failed, cmpl status %d\n",
   1296			destroy_kcqe->completion_status);
   1297		return;
   1298	} else {
   1299		/* destroy successful */
   1300		BNX2FC_TGT_DBG(tgt, "upload successful\n");
   1301		clear_bit(BNX2FC_FLAG_DISABLED, &tgt->flags);
   1302		set_bit(BNX2FC_FLAG_DESTROYED, &tgt->flags);
   1303		set_bit(BNX2FC_FLAG_UPLD_REQ_COMPL, &tgt->flags);
   1304		wake_up_interruptible(&tgt->upld_wait);
   1305	}
   1306}
   1307
   1308static void bnx2fc_init_failure(struct bnx2fc_hba *hba, u32 err_code)
   1309{
   1310	switch (err_code) {
   1311	case FCOE_KCQE_COMPLETION_STATUS_INVALID_OPCODE:
   1312		printk(KERN_ERR PFX "init_failure due to invalid opcode\n");
   1313		break;
   1314
   1315	case FCOE_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE:
   1316		printk(KERN_ERR PFX "init failed due to ctx alloc failure\n");
   1317		break;
   1318
   1319	case FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR:
   1320		printk(KERN_ERR PFX "init_failure due to NIC error\n");
   1321		break;
   1322	case FCOE_KCQE_COMPLETION_STATUS_ERROR:
   1323		printk(KERN_ERR PFX "init failure due to compl status err\n");
   1324		break;
   1325	case FCOE_KCQE_COMPLETION_STATUS_WRONG_HSI_VERSION:
   1326		printk(KERN_ERR PFX "init failure due to HSI mismatch\n");
   1327		break;
   1328	default:
   1329		printk(KERN_ERR PFX "Unknown Error code %d\n", err_code);
   1330	}
   1331}
   1332
   1333/**
   1334 * bnx2fc_indicate_kcqe() - process KCQE
   1335 *
   1336 * @context:	adapter structure pointer
   1337 * @kcq:	kcqe pointer
   1338 * @num_cqe:	Number of completion queue elements
   1339 *
   1340 * Generic KCQ event handler
   1341 */
   1342void bnx2fc_indicate_kcqe(void *context, struct kcqe *kcq[],
   1343					u32 num_cqe)
   1344{
   1345	struct bnx2fc_hba *hba = (struct bnx2fc_hba *)context;
   1346	int i = 0;
   1347	struct fcoe_kcqe *kcqe = NULL;
   1348
   1349	while (i < num_cqe) {
   1350		kcqe = (struct fcoe_kcqe *) kcq[i++];
   1351
   1352		switch (kcqe->op_code) {
   1353		case FCOE_KCQE_OPCODE_CQ_EVENT_NOTIFICATION:
   1354			bnx2fc_fastpath_notification(hba, kcqe);
   1355			break;
   1356
   1357		case FCOE_KCQE_OPCODE_OFFLOAD_CONN:
   1358			bnx2fc_process_ofld_cmpl(hba, kcqe);
   1359			break;
   1360
   1361		case FCOE_KCQE_OPCODE_ENABLE_CONN:
   1362			bnx2fc_process_enable_conn_cmpl(hba, kcqe);
   1363			break;
   1364
   1365		case FCOE_KCQE_OPCODE_INIT_FUNC:
   1366			if (kcqe->completion_status !=
   1367					FCOE_KCQE_COMPLETION_STATUS_SUCCESS) {
   1368				bnx2fc_init_failure(hba,
   1369						kcqe->completion_status);
   1370			} else {
   1371				set_bit(ADAPTER_STATE_UP, &hba->adapter_state);
   1372				bnx2fc_get_link_state(hba);
   1373				printk(KERN_INFO PFX "[%.2x]: FCOE_INIT passed\n",
   1374					(u8)hba->pcidev->bus->number);
   1375			}
   1376			break;
   1377
   1378		case FCOE_KCQE_OPCODE_DESTROY_FUNC:
   1379			if (kcqe->completion_status !=
   1380					FCOE_KCQE_COMPLETION_STATUS_SUCCESS) {
   1381
   1382				printk(KERN_ERR PFX "DESTROY failed\n");
   1383			} else {
   1384				printk(KERN_ERR PFX "DESTROY success\n");
   1385			}
   1386			set_bit(BNX2FC_FLAG_DESTROY_CMPL, &hba->flags);
   1387			wake_up_interruptible(&hba->destroy_wait);
   1388			break;
   1389
   1390		case FCOE_KCQE_OPCODE_DISABLE_CONN:
   1391			bnx2fc_process_conn_disable_cmpl(hba, kcqe);
   1392			break;
   1393
   1394		case FCOE_KCQE_OPCODE_DESTROY_CONN:
   1395			bnx2fc_process_conn_destroy_cmpl(hba, kcqe);
   1396			break;
   1397
   1398		case FCOE_KCQE_OPCODE_STAT_FUNC:
   1399			if (kcqe->completion_status !=
   1400			    FCOE_KCQE_COMPLETION_STATUS_SUCCESS)
   1401				printk(KERN_ERR PFX "STAT failed\n");
   1402			complete(&hba->stat_req_done);
   1403			break;
   1404
   1405		case FCOE_KCQE_OPCODE_FCOE_ERROR:
   1406		default:
   1407			printk(KERN_ERR PFX "unknown opcode 0x%x\n",
   1408								kcqe->op_code);
   1409		}
   1410	}
   1411}
   1412
   1413void bnx2fc_add_2_sq(struct bnx2fc_rport *tgt, u16 xid)
   1414{
   1415	struct fcoe_sqe *sqe;
   1416
   1417	sqe = &tgt->sq[tgt->sq_prod_idx];
   1418
   1419	/* Fill SQ WQE */
   1420	sqe->wqe = xid << FCOE_SQE_TASK_ID_SHIFT;
   1421	sqe->wqe |= tgt->sq_curr_toggle_bit << FCOE_SQE_TOGGLE_BIT_SHIFT;
   1422
   1423	/* Advance SQ Prod Idx */
   1424	if (++tgt->sq_prod_idx == BNX2FC_SQ_WQES_MAX) {
   1425		tgt->sq_prod_idx = 0;
   1426		tgt->sq_curr_toggle_bit = 1 - tgt->sq_curr_toggle_bit;
   1427	}
   1428}
   1429
   1430void bnx2fc_ring_doorbell(struct bnx2fc_rport *tgt)
   1431{
   1432	struct b577xx_doorbell_set_prod *sq_db = &tgt->sq_db;
   1433	u32 msg;
   1434
   1435	wmb();
   1436	sq_db->prod = tgt->sq_prod_idx |
   1437				(tgt->sq_curr_toggle_bit << 15);
   1438	msg = *((u32 *)sq_db);
   1439	writel(cpu_to_le32(msg), tgt->ctx_base);
   1440
   1441}
   1442
   1443int bnx2fc_map_doorbell(struct bnx2fc_rport *tgt)
   1444{
   1445	u32 context_id = tgt->context_id;
   1446	struct fcoe_port *port = tgt->port;
   1447	u32 reg_off;
   1448	resource_size_t reg_base;
   1449	struct bnx2fc_interface *interface = port->priv;
   1450	struct bnx2fc_hba *hba = interface->hba;
   1451
   1452	reg_base = pci_resource_start(hba->pcidev,
   1453					BNX2X_DOORBELL_PCI_BAR);
   1454	reg_off = (1 << BNX2X_DB_SHIFT) * (context_id & 0x1FFFF);
   1455	tgt->ctx_base = ioremap(reg_base + reg_off, 4);
   1456	if (!tgt->ctx_base)
   1457		return -ENOMEM;
   1458	return 0;
   1459}
   1460
   1461char *bnx2fc_get_next_rqe(struct bnx2fc_rport *tgt, u8 num_items)
   1462{
   1463	char *buf = (char *)tgt->rq + (tgt->rq_cons_idx * BNX2FC_RQ_BUF_SZ);
   1464
   1465	if (tgt->rq_cons_idx + num_items > BNX2FC_RQ_WQES_MAX)
   1466		return NULL;
   1467
   1468	tgt->rq_cons_idx += num_items;
   1469
   1470	if (tgt->rq_cons_idx >= BNX2FC_RQ_WQES_MAX)
   1471		tgt->rq_cons_idx -= BNX2FC_RQ_WQES_MAX;
   1472
   1473	return buf;
   1474}
   1475
   1476void bnx2fc_return_rqe(struct bnx2fc_rport *tgt, u8 num_items)
   1477{
   1478	/* return the rq buffer */
   1479	u32 next_prod_idx = tgt->rq_prod_idx + num_items;
   1480	if ((next_prod_idx & 0x7fff) == BNX2FC_RQ_WQES_MAX) {
   1481		/* Wrap around RQ */
   1482		next_prod_idx += 0x8000 - BNX2FC_RQ_WQES_MAX;
   1483	}
   1484	tgt->rq_prod_idx = next_prod_idx;
   1485	tgt->conn_db->rq_prod = tgt->rq_prod_idx;
   1486}
   1487
   1488void bnx2fc_init_seq_cleanup_task(struct bnx2fc_cmd *seq_clnp_req,
   1489				  struct fcoe_task_ctx_entry *task,
   1490				  struct bnx2fc_cmd *orig_io_req,
   1491				  u32 offset)
   1492{
   1493	struct scsi_cmnd *sc_cmd = orig_io_req->sc_cmd;
   1494	struct bnx2fc_rport *tgt = seq_clnp_req->tgt;
   1495	struct fcoe_bd_ctx *bd = orig_io_req->bd_tbl->bd_tbl;
   1496	struct fcoe_ext_mul_sges_ctx *sgl;
   1497	u8 task_type = FCOE_TASK_TYPE_SEQUENCE_CLEANUP;
   1498	u8 orig_task_type;
   1499	u16 orig_xid = orig_io_req->xid;
   1500	u32 context_id = tgt->context_id;
   1501	u64 phys_addr = (u64)orig_io_req->bd_tbl->bd_tbl_dma;
   1502	u32 orig_offset = offset;
   1503	int bd_count;
   1504	int i;
   1505
   1506	memset(task, 0, sizeof(struct fcoe_task_ctx_entry));
   1507
   1508	if (sc_cmd->sc_data_direction == DMA_TO_DEVICE)
   1509		orig_task_type = FCOE_TASK_TYPE_WRITE;
   1510	else
   1511		orig_task_type = FCOE_TASK_TYPE_READ;
   1512
   1513	/* Tx flags */
   1514	task->txwr_rxrd.const_ctx.tx_flags =
   1515				FCOE_TASK_TX_STATE_SEQUENCE_CLEANUP <<
   1516				FCOE_TCE_TX_WR_RX_RD_CONST_TX_STATE_SHIFT;
   1517	/* init flags */
   1518	task->txwr_rxrd.const_ctx.init_flags = task_type <<
   1519				FCOE_TCE_TX_WR_RX_RD_CONST_TASK_TYPE_SHIFT;
   1520	task->txwr_rxrd.const_ctx.init_flags |= FCOE_TASK_CLASS_TYPE_3 <<
   1521				FCOE_TCE_TX_WR_RX_RD_CONST_CLASS_TYPE_SHIFT;
   1522	task->rxwr_txrd.const_ctx.init_flags = context_id <<
   1523				FCOE_TCE_RX_WR_TX_RD_CONST_CID_SHIFT;
   1524	task->rxwr_txrd.const_ctx.init_flags = context_id <<
   1525				FCOE_TCE_RX_WR_TX_RD_CONST_CID_SHIFT;
   1526
   1527	task->txwr_rxrd.union_ctx.cleanup.ctx.cleaned_task_id = orig_xid;
   1528
   1529	task->txwr_rxrd.union_ctx.cleanup.ctx.rolled_tx_seq_cnt = 0;
   1530	task->txwr_rxrd.union_ctx.cleanup.ctx.rolled_tx_data_offset = offset;
   1531
   1532	bd_count = orig_io_req->bd_tbl->bd_valid;
   1533
   1534	/* obtain the appropriate bd entry from relative offset */
   1535	for (i = 0; i < bd_count; i++) {
   1536		if (offset < bd[i].buf_len)
   1537			break;
   1538		offset -= bd[i].buf_len;
   1539	}
   1540	phys_addr += (i * sizeof(struct fcoe_bd_ctx));
   1541
   1542	if (orig_task_type == FCOE_TASK_TYPE_WRITE) {
   1543		task->txwr_only.sgl_ctx.sgl.mul_sgl.cur_sge_addr.lo =
   1544				(u32)phys_addr;
   1545		task->txwr_only.sgl_ctx.sgl.mul_sgl.cur_sge_addr.hi =
   1546				(u32)((u64)phys_addr >> 32);
   1547		task->txwr_only.sgl_ctx.sgl.mul_sgl.sgl_size =
   1548				bd_count;
   1549		task->txwr_only.sgl_ctx.sgl.mul_sgl.cur_sge_off =
   1550				offset; /* adjusted offset */
   1551		task->txwr_only.sgl_ctx.sgl.mul_sgl.cur_sge_idx = i;
   1552	} else {
   1553
   1554		/* Multiple SGEs were used for this IO */
   1555		sgl = &task->rxwr_only.union_ctx.read_info.sgl_ctx.sgl;
   1556		sgl->mul_sgl.cur_sge_addr.lo = (u32)phys_addr;
   1557		sgl->mul_sgl.cur_sge_addr.hi = (u32)((u64)phys_addr >> 32);
   1558		sgl->mul_sgl.sgl_size = bd_count;
   1559		sgl->mul_sgl.cur_sge_off = offset; /*adjusted offset */
   1560		sgl->mul_sgl.cur_sge_idx = i;
   1561
   1562		memset(&task->rxwr_only.rx_seq_ctx, 0,
   1563		       sizeof(struct fcoe_rx_seq_ctx));
   1564		task->rxwr_only.rx_seq_ctx.low_exp_ro = orig_offset;
   1565		task->rxwr_only.rx_seq_ctx.high_exp_ro = orig_offset;
   1566	}
   1567}
   1568void bnx2fc_init_cleanup_task(struct bnx2fc_cmd *io_req,
   1569			      struct fcoe_task_ctx_entry *task,
   1570			      u16 orig_xid)
   1571{
   1572	u8 task_type = FCOE_TASK_TYPE_EXCHANGE_CLEANUP;
   1573	struct bnx2fc_rport *tgt = io_req->tgt;
   1574	u32 context_id = tgt->context_id;
   1575
   1576	memset(task, 0, sizeof(struct fcoe_task_ctx_entry));
   1577
   1578	/* Tx Write Rx Read */
   1579	/* init flags */
   1580	task->txwr_rxrd.const_ctx.init_flags = task_type <<
   1581				FCOE_TCE_TX_WR_RX_RD_CONST_TASK_TYPE_SHIFT;
   1582	task->txwr_rxrd.const_ctx.init_flags |= FCOE_TASK_CLASS_TYPE_3 <<
   1583				FCOE_TCE_TX_WR_RX_RD_CONST_CLASS_TYPE_SHIFT;
   1584	if (tgt->dev_type == TYPE_TAPE)
   1585		task->txwr_rxrd.const_ctx.init_flags |=
   1586				FCOE_TASK_DEV_TYPE_TAPE <<
   1587				FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE_SHIFT;
   1588	else
   1589		task->txwr_rxrd.const_ctx.init_flags |=
   1590				FCOE_TASK_DEV_TYPE_DISK <<
   1591				FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE_SHIFT;
   1592	task->txwr_rxrd.union_ctx.cleanup.ctx.cleaned_task_id = orig_xid;
   1593
   1594	/* Tx flags */
   1595	task->txwr_rxrd.const_ctx.tx_flags =
   1596				FCOE_TASK_TX_STATE_EXCHANGE_CLEANUP <<
   1597				FCOE_TCE_TX_WR_RX_RD_CONST_TX_STATE_SHIFT;
   1598
   1599	/* Rx Read Tx Write */
   1600	task->rxwr_txrd.const_ctx.init_flags = context_id <<
   1601				FCOE_TCE_RX_WR_TX_RD_CONST_CID_SHIFT;
   1602	task->rxwr_txrd.var_ctx.rx_flags |= 1 <<
   1603				FCOE_TCE_RX_WR_TX_RD_VAR_EXP_FIRST_FRAME_SHIFT;
   1604}
   1605
   1606void bnx2fc_init_mp_task(struct bnx2fc_cmd *io_req,
   1607				struct fcoe_task_ctx_entry *task)
   1608{
   1609	struct bnx2fc_mp_req *mp_req = &(io_req->mp_req);
   1610	struct bnx2fc_rport *tgt = io_req->tgt;
   1611	struct fc_frame_header *fc_hdr;
   1612	struct fcoe_ext_mul_sges_ctx *sgl;
   1613	u8 task_type = 0;
   1614	u64 *hdr;
   1615	u64 temp_hdr[3];
   1616	u32 context_id;
   1617
   1618
   1619	/* Obtain task_type */
   1620	if ((io_req->cmd_type == BNX2FC_TASK_MGMT_CMD) ||
   1621	    (io_req->cmd_type == BNX2FC_ELS)) {
   1622		task_type = FCOE_TASK_TYPE_MIDPATH;
   1623	} else if (io_req->cmd_type == BNX2FC_ABTS) {
   1624		task_type = FCOE_TASK_TYPE_ABTS;
   1625	}
   1626
   1627	memset(task, 0, sizeof(struct fcoe_task_ctx_entry));
   1628
   1629	/* Setup the task from io_req for easy reference */
   1630	io_req->task = task;
   1631
   1632	BNX2FC_IO_DBG(io_req, "Init MP task for cmd_type = %d task_type = %d\n",
   1633		io_req->cmd_type, task_type);
   1634
   1635	/* Tx only */
   1636	if ((task_type == FCOE_TASK_TYPE_MIDPATH) ||
   1637	    (task_type == FCOE_TASK_TYPE_UNSOLICITED)) {
   1638		task->txwr_only.sgl_ctx.sgl.mul_sgl.cur_sge_addr.lo =
   1639				(u32)mp_req->mp_req_bd_dma;
   1640		task->txwr_only.sgl_ctx.sgl.mul_sgl.cur_sge_addr.hi =
   1641				(u32)((u64)mp_req->mp_req_bd_dma >> 32);
   1642		task->txwr_only.sgl_ctx.sgl.mul_sgl.sgl_size = 1;
   1643	}
   1644
   1645	/* Tx Write Rx Read */
   1646	/* init flags */
   1647	task->txwr_rxrd.const_ctx.init_flags = task_type <<
   1648				FCOE_TCE_TX_WR_RX_RD_CONST_TASK_TYPE_SHIFT;
   1649	if (tgt->dev_type == TYPE_TAPE)
   1650		task->txwr_rxrd.const_ctx.init_flags |=
   1651				FCOE_TASK_DEV_TYPE_TAPE <<
   1652				FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE_SHIFT;
   1653	else
   1654		task->txwr_rxrd.const_ctx.init_flags |=
   1655				FCOE_TASK_DEV_TYPE_DISK <<
   1656				FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE_SHIFT;
   1657	task->txwr_rxrd.const_ctx.init_flags |= FCOE_TASK_CLASS_TYPE_3 <<
   1658				FCOE_TCE_TX_WR_RX_RD_CONST_CLASS_TYPE_SHIFT;
   1659
   1660	/* tx flags */
   1661	task->txwr_rxrd.const_ctx.tx_flags = FCOE_TASK_TX_STATE_INIT <<
   1662				FCOE_TCE_TX_WR_RX_RD_CONST_TX_STATE_SHIFT;
   1663
   1664	/* Rx Write Tx Read */
   1665	task->rxwr_txrd.const_ctx.data_2_trns = io_req->data_xfer_len;
   1666
   1667	/* rx flags */
   1668	task->rxwr_txrd.var_ctx.rx_flags |= 1 <<
   1669				FCOE_TCE_RX_WR_TX_RD_VAR_EXP_FIRST_FRAME_SHIFT;
   1670
   1671	context_id = tgt->context_id;
   1672	task->rxwr_txrd.const_ctx.init_flags = context_id <<
   1673				FCOE_TCE_RX_WR_TX_RD_CONST_CID_SHIFT;
   1674
   1675	fc_hdr = &(mp_req->req_fc_hdr);
   1676	if (task_type == FCOE_TASK_TYPE_MIDPATH) {
   1677		fc_hdr->fh_ox_id = cpu_to_be16(io_req->xid);
   1678		fc_hdr->fh_rx_id = htons(0xffff);
   1679		task->rxwr_txrd.var_ctx.rx_id = 0xffff;
   1680	} else if (task_type == FCOE_TASK_TYPE_UNSOLICITED) {
   1681		fc_hdr->fh_rx_id = cpu_to_be16(io_req->xid);
   1682	}
   1683
   1684	/* Fill FC Header into middle path buffer */
   1685	hdr = (u64 *) &task->txwr_rxrd.union_ctx.tx_frame.fc_hdr;
   1686	memcpy(temp_hdr, fc_hdr, sizeof(temp_hdr));
   1687	hdr[0] = cpu_to_be64(temp_hdr[0]);
   1688	hdr[1] = cpu_to_be64(temp_hdr[1]);
   1689	hdr[2] = cpu_to_be64(temp_hdr[2]);
   1690
   1691	/* Rx Only */
   1692	if (task_type == FCOE_TASK_TYPE_MIDPATH) {
   1693		sgl = &task->rxwr_only.union_ctx.read_info.sgl_ctx.sgl;
   1694
   1695		sgl->mul_sgl.cur_sge_addr.lo = (u32)mp_req->mp_resp_bd_dma;
   1696		sgl->mul_sgl.cur_sge_addr.hi =
   1697				(u32)((u64)mp_req->mp_resp_bd_dma >> 32);
   1698		sgl->mul_sgl.sgl_size = 1;
   1699	}
   1700}
   1701
   1702void bnx2fc_init_task(struct bnx2fc_cmd *io_req,
   1703			     struct fcoe_task_ctx_entry *task)
   1704{
   1705	u8 task_type;
   1706	struct scsi_cmnd *sc_cmd = io_req->sc_cmd;
   1707	struct io_bdt *bd_tbl = io_req->bd_tbl;
   1708	struct bnx2fc_rport *tgt = io_req->tgt;
   1709	struct fcoe_cached_sge_ctx *cached_sge;
   1710	struct fcoe_ext_mul_sges_ctx *sgl;
   1711	int dev_type = tgt->dev_type;
   1712	u64 *fcp_cmnd;
   1713	u64 tmp_fcp_cmnd[4];
   1714	u32 context_id;
   1715	int cnt, i;
   1716	int bd_count;
   1717
   1718	memset(task, 0, sizeof(struct fcoe_task_ctx_entry));
   1719
   1720	/* Setup the task from io_req for easy reference */
   1721	io_req->task = task;
   1722
   1723	if (sc_cmd->sc_data_direction == DMA_TO_DEVICE)
   1724		task_type = FCOE_TASK_TYPE_WRITE;
   1725	else
   1726		task_type = FCOE_TASK_TYPE_READ;
   1727
   1728	/* Tx only */
   1729	bd_count = bd_tbl->bd_valid;
   1730	cached_sge = &task->rxwr_only.union_ctx.read_info.sgl_ctx.cached_sge;
   1731	if (task_type == FCOE_TASK_TYPE_WRITE) {
   1732		if ((dev_type == TYPE_DISK) && (bd_count == 1)) {
   1733			struct fcoe_bd_ctx *fcoe_bd_tbl = bd_tbl->bd_tbl;
   1734
   1735			task->txwr_only.sgl_ctx.cached_sge.cur_buf_addr.lo =
   1736			cached_sge->cur_buf_addr.lo =
   1737					fcoe_bd_tbl->buf_addr_lo;
   1738			task->txwr_only.sgl_ctx.cached_sge.cur_buf_addr.hi =
   1739			cached_sge->cur_buf_addr.hi =
   1740					fcoe_bd_tbl->buf_addr_hi;
   1741			task->txwr_only.sgl_ctx.cached_sge.cur_buf_rem =
   1742			cached_sge->cur_buf_rem =
   1743					fcoe_bd_tbl->buf_len;
   1744
   1745			task->txwr_rxrd.const_ctx.init_flags |= 1 <<
   1746				FCOE_TCE_TX_WR_RX_RD_CONST_CACHED_SGE_SHIFT;
   1747		} else {
   1748			task->txwr_only.sgl_ctx.sgl.mul_sgl.cur_sge_addr.lo =
   1749					(u32)bd_tbl->bd_tbl_dma;
   1750			task->txwr_only.sgl_ctx.sgl.mul_sgl.cur_sge_addr.hi =
   1751					(u32)((u64)bd_tbl->bd_tbl_dma >> 32);
   1752			task->txwr_only.sgl_ctx.sgl.mul_sgl.sgl_size =
   1753					bd_tbl->bd_valid;
   1754		}
   1755	}
   1756
   1757	/*Tx Write Rx Read */
   1758	/* Init state to NORMAL */
   1759	task->txwr_rxrd.const_ctx.init_flags |= task_type <<
   1760				FCOE_TCE_TX_WR_RX_RD_CONST_TASK_TYPE_SHIFT;
   1761	if (dev_type == TYPE_TAPE) {
   1762		task->txwr_rxrd.const_ctx.init_flags |=
   1763				FCOE_TASK_DEV_TYPE_TAPE <<
   1764				FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE_SHIFT;
   1765		io_req->rec_retry = 0;
   1766		io_req->rec_retry = 0;
   1767	} else
   1768		task->txwr_rxrd.const_ctx.init_flags |=
   1769				FCOE_TASK_DEV_TYPE_DISK <<
   1770				FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE_SHIFT;
   1771	task->txwr_rxrd.const_ctx.init_flags |= FCOE_TASK_CLASS_TYPE_3 <<
   1772				FCOE_TCE_TX_WR_RX_RD_CONST_CLASS_TYPE_SHIFT;
   1773	/* tx flags */
   1774	task->txwr_rxrd.const_ctx.tx_flags = FCOE_TASK_TX_STATE_NORMAL <<
   1775				FCOE_TCE_TX_WR_RX_RD_CONST_TX_STATE_SHIFT;
   1776
   1777	/* Set initial seq counter */
   1778	task->txwr_rxrd.union_ctx.tx_seq.ctx.seq_cnt = 1;
   1779
   1780	/* Fill FCP_CMND IU */
   1781	fcp_cmnd = (u64 *)
   1782		    task->txwr_rxrd.union_ctx.fcp_cmd.opaque;
   1783	bnx2fc_build_fcp_cmnd(io_req, (struct fcp_cmnd *)&tmp_fcp_cmnd);
   1784
   1785	/* swap fcp_cmnd */
   1786	cnt = sizeof(struct fcp_cmnd) / sizeof(u64);
   1787
   1788	for (i = 0; i < cnt; i++) {
   1789		*fcp_cmnd = cpu_to_be64(tmp_fcp_cmnd[i]);
   1790		fcp_cmnd++;
   1791	}
   1792
   1793	/* Rx Write Tx Read */
   1794	task->rxwr_txrd.const_ctx.data_2_trns = io_req->data_xfer_len;
   1795
   1796	context_id = tgt->context_id;
   1797	task->rxwr_txrd.const_ctx.init_flags = context_id <<
   1798				FCOE_TCE_RX_WR_TX_RD_CONST_CID_SHIFT;
   1799
   1800	/* rx flags */
   1801	/* Set state to "waiting for the first packet" */
   1802	task->rxwr_txrd.var_ctx.rx_flags |= 1 <<
   1803				FCOE_TCE_RX_WR_TX_RD_VAR_EXP_FIRST_FRAME_SHIFT;
   1804
   1805	task->rxwr_txrd.var_ctx.rx_id = 0xffff;
   1806
   1807	/* Rx Only */
   1808	if (task_type != FCOE_TASK_TYPE_READ)
   1809		return;
   1810
   1811	sgl = &task->rxwr_only.union_ctx.read_info.sgl_ctx.sgl;
   1812	bd_count = bd_tbl->bd_valid;
   1813
   1814	if (dev_type == TYPE_DISK) {
   1815		if (bd_count == 1) {
   1816
   1817			struct fcoe_bd_ctx *fcoe_bd_tbl = bd_tbl->bd_tbl;
   1818
   1819			cached_sge->cur_buf_addr.lo = fcoe_bd_tbl->buf_addr_lo;
   1820			cached_sge->cur_buf_addr.hi = fcoe_bd_tbl->buf_addr_hi;
   1821			cached_sge->cur_buf_rem = fcoe_bd_tbl->buf_len;
   1822			task->txwr_rxrd.const_ctx.init_flags |= 1 <<
   1823				FCOE_TCE_TX_WR_RX_RD_CONST_CACHED_SGE_SHIFT;
   1824		} else if (bd_count == 2) {
   1825			struct fcoe_bd_ctx *fcoe_bd_tbl = bd_tbl->bd_tbl;
   1826
   1827			cached_sge->cur_buf_addr.lo = fcoe_bd_tbl->buf_addr_lo;
   1828			cached_sge->cur_buf_addr.hi = fcoe_bd_tbl->buf_addr_hi;
   1829			cached_sge->cur_buf_rem = fcoe_bd_tbl->buf_len;
   1830
   1831			fcoe_bd_tbl++;
   1832			cached_sge->second_buf_addr.lo =
   1833						 fcoe_bd_tbl->buf_addr_lo;
   1834			cached_sge->second_buf_addr.hi =
   1835						fcoe_bd_tbl->buf_addr_hi;
   1836			cached_sge->second_buf_rem = fcoe_bd_tbl->buf_len;
   1837			task->txwr_rxrd.const_ctx.init_flags |= 1 <<
   1838				FCOE_TCE_TX_WR_RX_RD_CONST_CACHED_SGE_SHIFT;
   1839		} else {
   1840
   1841			sgl->mul_sgl.cur_sge_addr.lo = (u32)bd_tbl->bd_tbl_dma;
   1842			sgl->mul_sgl.cur_sge_addr.hi =
   1843					(u32)((u64)bd_tbl->bd_tbl_dma >> 32);
   1844			sgl->mul_sgl.sgl_size = bd_count;
   1845		}
   1846	} else {
   1847		sgl->mul_sgl.cur_sge_addr.lo = (u32)bd_tbl->bd_tbl_dma;
   1848		sgl->mul_sgl.cur_sge_addr.hi =
   1849				(u32)((u64)bd_tbl->bd_tbl_dma >> 32);
   1850		sgl->mul_sgl.sgl_size = bd_count;
   1851	}
   1852}
   1853
   1854/**
   1855 * bnx2fc_setup_task_ctx - allocate and map task context
   1856 *
   1857 * @hba:	pointer to adapter structure
   1858 *
   1859 * allocate memory for task context, and associated BD table to be used
   1860 * by firmware
   1861 *
   1862 */
   1863int bnx2fc_setup_task_ctx(struct bnx2fc_hba *hba)
   1864{
   1865	int rc = 0;
   1866	struct regpair *task_ctx_bdt;
   1867	dma_addr_t addr;
   1868	int task_ctx_arr_sz;
   1869	int i;
   1870
   1871	/*
   1872	 * Allocate task context bd table. A page size of bd table
   1873	 * can map 256 buffers. Each buffer contains 32 task context
   1874	 * entries. Hence the limit with one page is 8192 task context
   1875	 * entries.
   1876	 */
   1877	hba->task_ctx_bd_tbl = dma_alloc_coherent(&hba->pcidev->dev,
   1878						  PAGE_SIZE,
   1879						  &hba->task_ctx_bd_dma,
   1880						  GFP_KERNEL);
   1881	if (!hba->task_ctx_bd_tbl) {
   1882		printk(KERN_ERR PFX "unable to allocate task context BDT\n");
   1883		rc = -1;
   1884		goto out;
   1885	}
   1886
   1887	/*
   1888	 * Allocate task_ctx which is an array of pointers pointing to
   1889	 * a page containing 32 task contexts
   1890	 */
   1891	task_ctx_arr_sz = (hba->max_tasks / BNX2FC_TASKS_PER_PAGE);
   1892	hba->task_ctx = kzalloc((task_ctx_arr_sz * sizeof(void *)),
   1893				 GFP_KERNEL);
   1894	if (!hba->task_ctx) {
   1895		printk(KERN_ERR PFX "unable to allocate task context array\n");
   1896		rc = -1;
   1897		goto out1;
   1898	}
   1899
   1900	/*
   1901	 * Allocate task_ctx_dma which is an array of dma addresses
   1902	 */
   1903	hba->task_ctx_dma = kmalloc((task_ctx_arr_sz *
   1904					sizeof(dma_addr_t)), GFP_KERNEL);
   1905	if (!hba->task_ctx_dma) {
   1906		printk(KERN_ERR PFX "unable to alloc context mapping array\n");
   1907		rc = -1;
   1908		goto out2;
   1909	}
   1910
   1911	task_ctx_bdt = (struct regpair *)hba->task_ctx_bd_tbl;
   1912	for (i = 0; i < task_ctx_arr_sz; i++) {
   1913
   1914		hba->task_ctx[i] = dma_alloc_coherent(&hba->pcidev->dev,
   1915						      PAGE_SIZE,
   1916						      &hba->task_ctx_dma[i],
   1917						      GFP_KERNEL);
   1918		if (!hba->task_ctx[i]) {
   1919			printk(KERN_ERR PFX "unable to alloc task context\n");
   1920			rc = -1;
   1921			goto out3;
   1922		}
   1923		addr = (u64)hba->task_ctx_dma[i];
   1924		task_ctx_bdt->hi = cpu_to_le32((u64)addr >> 32);
   1925		task_ctx_bdt->lo = cpu_to_le32((u32)addr);
   1926		task_ctx_bdt++;
   1927	}
   1928	return 0;
   1929
   1930out3:
   1931	for (i = 0; i < task_ctx_arr_sz; i++) {
   1932		if (hba->task_ctx[i]) {
   1933
   1934			dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE,
   1935				hba->task_ctx[i], hba->task_ctx_dma[i]);
   1936			hba->task_ctx[i] = NULL;
   1937		}
   1938	}
   1939
   1940	kfree(hba->task_ctx_dma);
   1941	hba->task_ctx_dma = NULL;
   1942out2:
   1943	kfree(hba->task_ctx);
   1944	hba->task_ctx = NULL;
   1945out1:
   1946	dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE,
   1947			hba->task_ctx_bd_tbl, hba->task_ctx_bd_dma);
   1948	hba->task_ctx_bd_tbl = NULL;
   1949out:
   1950	return rc;
   1951}
   1952
   1953void bnx2fc_free_task_ctx(struct bnx2fc_hba *hba)
   1954{
   1955	int task_ctx_arr_sz;
   1956	int i;
   1957
   1958	if (hba->task_ctx_bd_tbl) {
   1959		dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE,
   1960				    hba->task_ctx_bd_tbl,
   1961				    hba->task_ctx_bd_dma);
   1962		hba->task_ctx_bd_tbl = NULL;
   1963	}
   1964
   1965	task_ctx_arr_sz = (hba->max_tasks / BNX2FC_TASKS_PER_PAGE);
   1966	if (hba->task_ctx) {
   1967		for (i = 0; i < task_ctx_arr_sz; i++) {
   1968			if (hba->task_ctx[i]) {
   1969				dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE,
   1970						    hba->task_ctx[i],
   1971						    hba->task_ctx_dma[i]);
   1972				hba->task_ctx[i] = NULL;
   1973			}
   1974		}
   1975		kfree(hba->task_ctx);
   1976		hba->task_ctx = NULL;
   1977	}
   1978
   1979	kfree(hba->task_ctx_dma);
   1980	hba->task_ctx_dma = NULL;
   1981}
   1982
   1983static void bnx2fc_free_hash_table(struct bnx2fc_hba *hba)
   1984{
   1985	int i;
   1986	int segment_count;
   1987	u32 *pbl;
   1988
   1989	if (hba->hash_tbl_segments) {
   1990
   1991		pbl = hba->hash_tbl_pbl;
   1992		if (pbl) {
   1993			segment_count = hba->hash_tbl_segment_count;
   1994			for (i = 0; i < segment_count; ++i) {
   1995				dma_addr_t dma_address;
   1996
   1997				dma_address = le32_to_cpu(*pbl);
   1998				++pbl;
   1999				dma_address += ((u64)le32_to_cpu(*pbl)) << 32;
   2000				++pbl;
   2001				dma_free_coherent(&hba->pcidev->dev,
   2002						  BNX2FC_HASH_TBL_CHUNK_SIZE,
   2003						  hba->hash_tbl_segments[i],
   2004						  dma_address);
   2005			}
   2006		}
   2007
   2008		kfree(hba->hash_tbl_segments);
   2009		hba->hash_tbl_segments = NULL;
   2010	}
   2011
   2012	if (hba->hash_tbl_pbl) {
   2013		dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE,
   2014				    hba->hash_tbl_pbl,
   2015				    hba->hash_tbl_pbl_dma);
   2016		hba->hash_tbl_pbl = NULL;
   2017	}
   2018}
   2019
   2020static int bnx2fc_allocate_hash_table(struct bnx2fc_hba *hba)
   2021{
   2022	int i;
   2023	int hash_table_size;
   2024	int segment_count;
   2025	int segment_array_size;
   2026	int dma_segment_array_size;
   2027	dma_addr_t *dma_segment_array;
   2028	u32 *pbl;
   2029
   2030	hash_table_size = BNX2FC_NUM_MAX_SESS * BNX2FC_MAX_ROWS_IN_HASH_TBL *
   2031		sizeof(struct fcoe_hash_table_entry);
   2032
   2033	segment_count = hash_table_size + BNX2FC_HASH_TBL_CHUNK_SIZE - 1;
   2034	segment_count /= BNX2FC_HASH_TBL_CHUNK_SIZE;
   2035	hba->hash_tbl_segment_count = segment_count;
   2036
   2037	segment_array_size = segment_count * sizeof(*hba->hash_tbl_segments);
   2038	hba->hash_tbl_segments = kzalloc(segment_array_size, GFP_KERNEL);
   2039	if (!hba->hash_tbl_segments) {
   2040		printk(KERN_ERR PFX "hash table pointers alloc failed\n");
   2041		return -ENOMEM;
   2042	}
   2043	dma_segment_array_size = segment_count * sizeof(*dma_segment_array);
   2044	dma_segment_array = kzalloc(dma_segment_array_size, GFP_KERNEL);
   2045	if (!dma_segment_array) {
   2046		printk(KERN_ERR PFX "hash table pointers (dma) alloc failed\n");
   2047		goto cleanup_ht;
   2048	}
   2049
   2050	for (i = 0; i < segment_count; ++i) {
   2051		hba->hash_tbl_segments[i] = dma_alloc_coherent(&hba->pcidev->dev,
   2052							       BNX2FC_HASH_TBL_CHUNK_SIZE,
   2053							       &dma_segment_array[i],
   2054							       GFP_KERNEL);
   2055		if (!hba->hash_tbl_segments[i]) {
   2056			printk(KERN_ERR PFX "hash segment alloc failed\n");
   2057			goto cleanup_dma;
   2058		}
   2059	}
   2060
   2061	hba->hash_tbl_pbl = dma_alloc_coherent(&hba->pcidev->dev, PAGE_SIZE,
   2062					       &hba->hash_tbl_pbl_dma,
   2063					       GFP_KERNEL);
   2064	if (!hba->hash_tbl_pbl) {
   2065		printk(KERN_ERR PFX "hash table pbl alloc failed\n");
   2066		goto cleanup_dma;
   2067	}
   2068
   2069	pbl = hba->hash_tbl_pbl;
   2070	for (i = 0; i < segment_count; ++i) {
   2071		u64 paddr = dma_segment_array[i];
   2072		*pbl = cpu_to_le32((u32) paddr);
   2073		++pbl;
   2074		*pbl = cpu_to_le32((u32) (paddr >> 32));
   2075		++pbl;
   2076	}
   2077	pbl = hba->hash_tbl_pbl;
   2078	i = 0;
   2079	while (*pbl && *(pbl + 1)) {
   2080		++pbl;
   2081		++pbl;
   2082		++i;
   2083	}
   2084	kfree(dma_segment_array);
   2085	return 0;
   2086
   2087cleanup_dma:
   2088	for (i = 0; i < segment_count; ++i) {
   2089		if (hba->hash_tbl_segments[i])
   2090			dma_free_coherent(&hba->pcidev->dev,
   2091					    BNX2FC_HASH_TBL_CHUNK_SIZE,
   2092					    hba->hash_tbl_segments[i],
   2093					    dma_segment_array[i]);
   2094	}
   2095
   2096	kfree(dma_segment_array);
   2097
   2098cleanup_ht:
   2099	kfree(hba->hash_tbl_segments);
   2100	hba->hash_tbl_segments = NULL;
   2101	return -ENOMEM;
   2102}
   2103
   2104/**
   2105 * bnx2fc_setup_fw_resc - Allocate and map hash table and dummy buffer
   2106 *
   2107 * @hba:	Pointer to adapter structure
   2108 *
   2109 */
   2110int bnx2fc_setup_fw_resc(struct bnx2fc_hba *hba)
   2111{
   2112	u64 addr;
   2113	u32 mem_size;
   2114	int i;
   2115
   2116	if (bnx2fc_allocate_hash_table(hba))
   2117		return -ENOMEM;
   2118
   2119	mem_size = BNX2FC_NUM_MAX_SESS * sizeof(struct regpair);
   2120	hba->t2_hash_tbl_ptr = dma_alloc_coherent(&hba->pcidev->dev, mem_size,
   2121						  &hba->t2_hash_tbl_ptr_dma,
   2122						  GFP_KERNEL);
   2123	if (!hba->t2_hash_tbl_ptr) {
   2124		printk(KERN_ERR PFX "unable to allocate t2 hash table ptr\n");
   2125		bnx2fc_free_fw_resc(hba);
   2126		return -ENOMEM;
   2127	}
   2128
   2129	mem_size = BNX2FC_NUM_MAX_SESS *
   2130				sizeof(struct fcoe_t2_hash_table_entry);
   2131	hba->t2_hash_tbl = dma_alloc_coherent(&hba->pcidev->dev, mem_size,
   2132					      &hba->t2_hash_tbl_dma,
   2133					      GFP_KERNEL);
   2134	if (!hba->t2_hash_tbl) {
   2135		printk(KERN_ERR PFX "unable to allocate t2 hash table\n");
   2136		bnx2fc_free_fw_resc(hba);
   2137		return -ENOMEM;
   2138	}
   2139	for (i = 0; i < BNX2FC_NUM_MAX_SESS; i++) {
   2140		addr = (unsigned long) hba->t2_hash_tbl_dma +
   2141			 ((i+1) * sizeof(struct fcoe_t2_hash_table_entry));
   2142		hba->t2_hash_tbl[i].next.lo = addr & 0xffffffff;
   2143		hba->t2_hash_tbl[i].next.hi = addr >> 32;
   2144	}
   2145
   2146	hba->dummy_buffer = dma_alloc_coherent(&hba->pcidev->dev,
   2147					       PAGE_SIZE, &hba->dummy_buf_dma,
   2148					       GFP_KERNEL);
   2149	if (!hba->dummy_buffer) {
   2150		printk(KERN_ERR PFX "unable to alloc MP Dummy Buffer\n");
   2151		bnx2fc_free_fw_resc(hba);
   2152		return -ENOMEM;
   2153	}
   2154
   2155	hba->stats_buffer = dma_alloc_coherent(&hba->pcidev->dev, PAGE_SIZE,
   2156					       &hba->stats_buf_dma,
   2157					       GFP_KERNEL);
   2158	if (!hba->stats_buffer) {
   2159		printk(KERN_ERR PFX "unable to alloc Stats Buffer\n");
   2160		bnx2fc_free_fw_resc(hba);
   2161		return -ENOMEM;
   2162	}
   2163
   2164	return 0;
   2165}
   2166
   2167void bnx2fc_free_fw_resc(struct bnx2fc_hba *hba)
   2168{
   2169	u32 mem_size;
   2170
   2171	if (hba->stats_buffer) {
   2172		dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE,
   2173				  hba->stats_buffer, hba->stats_buf_dma);
   2174		hba->stats_buffer = NULL;
   2175	}
   2176
   2177	if (hba->dummy_buffer) {
   2178		dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE,
   2179				  hba->dummy_buffer, hba->dummy_buf_dma);
   2180		hba->dummy_buffer = NULL;
   2181	}
   2182
   2183	if (hba->t2_hash_tbl_ptr) {
   2184		mem_size = BNX2FC_NUM_MAX_SESS * sizeof(struct regpair);
   2185		dma_free_coherent(&hba->pcidev->dev, mem_size,
   2186				    hba->t2_hash_tbl_ptr,
   2187				    hba->t2_hash_tbl_ptr_dma);
   2188		hba->t2_hash_tbl_ptr = NULL;
   2189	}
   2190
   2191	if (hba->t2_hash_tbl) {
   2192		mem_size = BNX2FC_NUM_MAX_SESS *
   2193			    sizeof(struct fcoe_t2_hash_table_entry);
   2194		dma_free_coherent(&hba->pcidev->dev, mem_size,
   2195				    hba->t2_hash_tbl, hba->t2_hash_tbl_dma);
   2196		hba->t2_hash_tbl = NULL;
   2197	}
   2198	bnx2fc_free_hash_table(hba);
   2199}