1 /* bnx2fc_hwi.c: Broadcom NetXtreme II Linux FCoE offload driver.
2 * This file contains the code that low level functions that interact
3 * with 57712 FCoE firmware.
5 * Copyright (c) 2008 - 2010 Broadcom Corporation
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation.
11 * Written by: Bhanu Prakash Gollapudi (bprakash@broadcom.com)
16 DECLARE_PER_CPU(struct bnx2fc_percpu_s
, bnx2fc_percpu
);
18 static void bnx2fc_fastpath_notification(struct bnx2fc_hba
*hba
,
19 struct fcoe_kcqe
*new_cqe_kcqe
);
20 static void bnx2fc_process_ofld_cmpl(struct bnx2fc_hba
*hba
,
21 struct fcoe_kcqe
*ofld_kcqe
);
22 static void bnx2fc_process_enable_conn_cmpl(struct bnx2fc_hba
*hba
,
23 struct fcoe_kcqe
*ofld_kcqe
);
24 static void bnx2fc_init_failure(struct bnx2fc_hba
*hba
, u32 err_code
);
25 static void bnx2fc_process_conn_destroy_cmpl(struct bnx2fc_hba
*hba
,
26 struct fcoe_kcqe
*destroy_kcqe
);
28 int bnx2fc_send_stat_req(struct bnx2fc_hba
*hba
)
30 struct fcoe_kwqe_stat stat_req
;
31 struct kwqe
*kwqe_arr
[2];
35 memset(&stat_req
, 0x00, sizeof(struct fcoe_kwqe_stat
));
36 stat_req
.hdr
.op_code
= FCOE_KWQE_OPCODE_STAT
;
38 (FCOE_KWQE_LAYER_CODE
<< FCOE_KWQE_HEADER_LAYER_CODE_SHIFT
);
40 stat_req
.stat_params_addr_lo
= (u32
) hba
->stats_buf_dma
;
41 stat_req
.stat_params_addr_hi
= (u32
) ((u64
)hba
->stats_buf_dma
>> 32);
43 kwqe_arr
[0] = (struct kwqe
*) &stat_req
;
45 if (hba
->cnic
&& hba
->cnic
->submit_kwqes
)
46 rc
= hba
->cnic
->submit_kwqes(hba
->cnic
, kwqe_arr
, num_kwqes
);
52 * bnx2fc_send_fw_fcoe_init_msg - initiates initial handshake with FCoE f/w
54 * @hba: adapter structure pointer
56 * Send down FCoE firmware init KWQEs which initiates the initial handshake
60 int bnx2fc_send_fw_fcoe_init_msg(struct bnx2fc_hba
*hba
)
62 struct fcoe_kwqe_init1 fcoe_init1
;
63 struct fcoe_kwqe_init2 fcoe_init2
;
64 struct fcoe_kwqe_init3 fcoe_init3
;
65 struct kwqe
*kwqe_arr
[3];
70 printk(KERN_ERR PFX
"hba->cnic NULL during fcoe fw init\n");
75 memset(&fcoe_init1
, 0x00, sizeof(struct fcoe_kwqe_init1
));
76 fcoe_init1
.hdr
.op_code
= FCOE_KWQE_OPCODE_INIT1
;
77 fcoe_init1
.hdr
.flags
= (FCOE_KWQE_LAYER_CODE
<<
78 FCOE_KWQE_HEADER_LAYER_CODE_SHIFT
);
80 fcoe_init1
.num_tasks
= BNX2FC_MAX_TASKS
;
81 fcoe_init1
.sq_num_wqes
= BNX2FC_SQ_WQES_MAX
;
82 fcoe_init1
.rq_num_wqes
= BNX2FC_RQ_WQES_MAX
;
83 fcoe_init1
.rq_buffer_log_size
= BNX2FC_RQ_BUF_LOG_SZ
;
84 fcoe_init1
.cq_num_wqes
= BNX2FC_CQ_WQES_MAX
;
85 fcoe_init1
.dummy_buffer_addr_lo
= (u32
) hba
->dummy_buf_dma
;
86 fcoe_init1
.dummy_buffer_addr_hi
= (u32
) ((u64
)hba
->dummy_buf_dma
>> 32);
87 fcoe_init1
.task_list_pbl_addr_lo
= (u32
) hba
->task_ctx_bd_dma
;
88 fcoe_init1
.task_list_pbl_addr_hi
=
89 (u32
) ((u64
) hba
->task_ctx_bd_dma
>> 32);
90 fcoe_init1
.mtu
= BNX2FC_MINI_JUMBO_MTU
;
92 fcoe_init1
.flags
= (PAGE_SHIFT
<<
93 FCOE_KWQE_INIT1_LOG_PAGE_SIZE_SHIFT
);
95 fcoe_init1
.num_sessions_log
= BNX2FC_NUM_MAX_SESS_LOG
;
98 memset(&fcoe_init2
, 0x00, sizeof(struct fcoe_kwqe_init2
));
99 fcoe_init2
.hdr
.op_code
= FCOE_KWQE_OPCODE_INIT2
;
100 fcoe_init2
.hdr
.flags
= (FCOE_KWQE_LAYER_CODE
<<
101 FCOE_KWQE_HEADER_LAYER_CODE_SHIFT
);
103 fcoe_init2
.hsi_major_version
= FCOE_HSI_MAJOR_VERSION
;
104 fcoe_init2
.hsi_minor_version
= FCOE_HSI_MINOR_VERSION
;
107 fcoe_init2
.hash_tbl_pbl_addr_lo
= (u32
) hba
->hash_tbl_pbl_dma
;
108 fcoe_init2
.hash_tbl_pbl_addr_hi
= (u32
)
109 ((u64
) hba
->hash_tbl_pbl_dma
>> 32);
111 fcoe_init2
.t2_hash_tbl_addr_lo
= (u32
) hba
->t2_hash_tbl_dma
;
112 fcoe_init2
.t2_hash_tbl_addr_hi
= (u32
)
113 ((u64
) hba
->t2_hash_tbl_dma
>> 32);
115 fcoe_init2
.t2_ptr_hash_tbl_addr_lo
= (u32
) hba
->t2_hash_tbl_ptr_dma
;
116 fcoe_init2
.t2_ptr_hash_tbl_addr_hi
= (u32
)
117 ((u64
) hba
->t2_hash_tbl_ptr_dma
>> 32);
119 fcoe_init2
.free_list_count
= BNX2FC_NUM_MAX_SESS
;
121 /* fill init3 KWQE */
122 memset(&fcoe_init3
, 0x00, sizeof(struct fcoe_kwqe_init3
));
123 fcoe_init3
.hdr
.op_code
= FCOE_KWQE_OPCODE_INIT3
;
124 fcoe_init3
.hdr
.flags
= (FCOE_KWQE_LAYER_CODE
<<
125 FCOE_KWQE_HEADER_LAYER_CODE_SHIFT
);
126 fcoe_init3
.error_bit_map_lo
= 0xffffffff;
127 fcoe_init3
.error_bit_map_hi
= 0xffffffff;
129 fcoe_init3
.perf_config
= 1;
131 kwqe_arr
[0] = (struct kwqe
*) &fcoe_init1
;
132 kwqe_arr
[1] = (struct kwqe
*) &fcoe_init2
;
133 kwqe_arr
[2] = (struct kwqe
*) &fcoe_init3
;
135 if (hba
->cnic
&& hba
->cnic
->submit_kwqes
)
136 rc
= hba
->cnic
->submit_kwqes(hba
->cnic
, kwqe_arr
, num_kwqes
);
140 int bnx2fc_send_fw_fcoe_destroy_msg(struct bnx2fc_hba
*hba
)
142 struct fcoe_kwqe_destroy fcoe_destroy
;
143 struct kwqe
*kwqe_arr
[2];
147 /* fill destroy KWQE */
148 memset(&fcoe_destroy
, 0x00, sizeof(struct fcoe_kwqe_destroy
));
149 fcoe_destroy
.hdr
.op_code
= FCOE_KWQE_OPCODE_DESTROY
;
150 fcoe_destroy
.hdr
.flags
= (FCOE_KWQE_LAYER_CODE
<<
151 FCOE_KWQE_HEADER_LAYER_CODE_SHIFT
);
152 kwqe_arr
[0] = (struct kwqe
*) &fcoe_destroy
;
154 if (hba
->cnic
&& hba
->cnic
->submit_kwqes
)
155 rc
= hba
->cnic
->submit_kwqes(hba
->cnic
, kwqe_arr
, num_kwqes
);
160 * bnx2fc_send_session_ofld_req - initiates FCoE Session offload process
162 * @port: port structure pointer
163 * @tgt: bnx2fc_rport structure pointer
165 int bnx2fc_send_session_ofld_req(struct fcoe_port
*port
,
166 struct bnx2fc_rport
*tgt
)
168 struct fc_lport
*lport
= port
->lport
;
169 struct bnx2fc_interface
*interface
= port
->priv
;
170 struct bnx2fc_hba
*hba
= interface
->hba
;
171 struct kwqe
*kwqe_arr
[4];
172 struct fcoe_kwqe_conn_offload1 ofld_req1
;
173 struct fcoe_kwqe_conn_offload2 ofld_req2
;
174 struct fcoe_kwqe_conn_offload3 ofld_req3
;
175 struct fcoe_kwqe_conn_offload4 ofld_req4
;
176 struct fc_rport_priv
*rdata
= tgt
->rdata
;
177 struct fc_rport
*rport
= tgt
->rport
;
183 /* Initialize offload request 1 structure */
184 memset(&ofld_req1
, 0x00, sizeof(struct fcoe_kwqe_conn_offload1
));
186 ofld_req1
.hdr
.op_code
= FCOE_KWQE_OPCODE_OFFLOAD_CONN1
;
187 ofld_req1
.hdr
.flags
=
188 (FCOE_KWQE_LAYER_CODE
<< FCOE_KWQE_HEADER_LAYER_CODE_SHIFT
);
191 conn_id
= (u16
)tgt
->fcoe_conn_id
;
192 ofld_req1
.fcoe_conn_id
= conn_id
;
195 ofld_req1
.sq_addr_lo
= (u32
) tgt
->sq_dma
;
196 ofld_req1
.sq_addr_hi
= (u32
)((u64
) tgt
->sq_dma
>> 32);
198 ofld_req1
.rq_pbl_addr_lo
= (u32
) tgt
->rq_pbl_dma
;
199 ofld_req1
.rq_pbl_addr_hi
= (u32
)((u64
) tgt
->rq_pbl_dma
>> 32);
201 ofld_req1
.rq_first_pbe_addr_lo
= (u32
) tgt
->rq_dma
;
202 ofld_req1
.rq_first_pbe_addr_hi
=
203 (u32
)((u64
) tgt
->rq_dma
>> 32);
205 ofld_req1
.rq_prod
= 0x8000;
207 /* Initialize offload request 2 structure */
208 memset(&ofld_req2
, 0x00, sizeof(struct fcoe_kwqe_conn_offload2
));
210 ofld_req2
.hdr
.op_code
= FCOE_KWQE_OPCODE_OFFLOAD_CONN2
;
211 ofld_req2
.hdr
.flags
=
212 (FCOE_KWQE_LAYER_CODE
<< FCOE_KWQE_HEADER_LAYER_CODE_SHIFT
);
214 ofld_req2
.tx_max_fc_pay_len
= rdata
->maxframe_size
;
216 ofld_req2
.cq_addr_lo
= (u32
) tgt
->cq_dma
;
217 ofld_req2
.cq_addr_hi
= (u32
)((u64
)tgt
->cq_dma
>> 32);
219 ofld_req2
.xferq_addr_lo
= (u32
) tgt
->xferq_dma
;
220 ofld_req2
.xferq_addr_hi
= (u32
)((u64
)tgt
->xferq_dma
>> 32);
222 ofld_req2
.conn_db_addr_lo
= (u32
)tgt
->conn_db_dma
;
223 ofld_req2
.conn_db_addr_hi
= (u32
)((u64
)tgt
->conn_db_dma
>> 32);
225 /* Initialize offload request 3 structure */
226 memset(&ofld_req3
, 0x00, sizeof(struct fcoe_kwqe_conn_offload3
));
228 ofld_req3
.hdr
.op_code
= FCOE_KWQE_OPCODE_OFFLOAD_CONN3
;
229 ofld_req3
.hdr
.flags
=
230 (FCOE_KWQE_LAYER_CODE
<< FCOE_KWQE_HEADER_LAYER_CODE_SHIFT
);
232 ofld_req3
.vlan_tag
= interface
->vlan_id
<<
233 FCOE_KWQE_CONN_OFFLOAD3_VLAN_ID_SHIFT
;
234 ofld_req3
.vlan_tag
|= 3 << FCOE_KWQE_CONN_OFFLOAD3_PRIORITY_SHIFT
;
236 port_id
= fc_host_port_id(lport
->host
);
238 BNX2FC_HBA_DBG(lport
, "ofld_req: port_id = 0, link down?\n");
243 * Store s_id of the initiator for further reference. This will
244 * be used during disable/destroy during linkdown processing as
245 * when the lport is reset, the port_id also is reset to 0
248 ofld_req3
.s_id
[0] = (port_id
& 0x000000FF);
249 ofld_req3
.s_id
[1] = (port_id
& 0x0000FF00) >> 8;
250 ofld_req3
.s_id
[2] = (port_id
& 0x00FF0000) >> 16;
252 port_id
= rport
->port_id
;
253 ofld_req3
.d_id
[0] = (port_id
& 0x000000FF);
254 ofld_req3
.d_id
[1] = (port_id
& 0x0000FF00) >> 8;
255 ofld_req3
.d_id
[2] = (port_id
& 0x00FF0000) >> 16;
257 ofld_req3
.tx_total_conc_seqs
= rdata
->max_seq
;
259 ofld_req3
.tx_max_conc_seqs_c3
= rdata
->max_seq
;
260 ofld_req3
.rx_max_fc_pay_len
= lport
->mfs
;
262 ofld_req3
.rx_total_conc_seqs
= BNX2FC_MAX_SEQS
;
263 ofld_req3
.rx_max_conc_seqs_c3
= BNX2FC_MAX_SEQS
;
264 ofld_req3
.rx_open_seqs_exch_c3
= 1;
266 ofld_req3
.confq_first_pbe_addr_lo
= tgt
->confq_dma
;
267 ofld_req3
.confq_first_pbe_addr_hi
= (u32
)((u64
) tgt
->confq_dma
>> 32);
269 /* set mul_n_port_ids supported flag to 0, until it is supported */
272 ofld_req3.flags |= (((lport->send_sp_features & FC_SP_FT_MNA) ? 1:0) <<
273 FCOE_KWQE_CONN_OFFLOAD3_B_MUL_N_PORT_IDS_SHIFT);
275 /* Info from PLOGI response */
276 ofld_req3
.flags
|= (((rdata
->sp_features
& FC_SP_FT_EDTR
) ? 1 : 0) <<
277 FCOE_KWQE_CONN_OFFLOAD3_B_E_D_TOV_RES_SHIFT
);
279 ofld_req3
.flags
|= (((rdata
->sp_features
& FC_SP_FT_SEQC
) ? 1 : 0) <<
280 FCOE_KWQE_CONN_OFFLOAD3_B_CONT_INCR_SEQ_CNT_SHIFT
);
283 ofld_req3
.flags
|= (interface
->vlan_enabled
<<
284 FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG_SHIFT
);
286 /* C2_VALID and ACK flags are not set as they are not suppported */
289 /* Initialize offload request 4 structure */
290 memset(&ofld_req4
, 0x00, sizeof(struct fcoe_kwqe_conn_offload4
));
291 ofld_req4
.hdr
.op_code
= FCOE_KWQE_OPCODE_OFFLOAD_CONN4
;
292 ofld_req4
.hdr
.flags
=
293 (FCOE_KWQE_LAYER_CODE
<< FCOE_KWQE_HEADER_LAYER_CODE_SHIFT
);
295 ofld_req4
.e_d_tov_timer_val
= lport
->e_d_tov
/ 20;
298 ofld_req4
.src_mac_addr_lo
[0] = port
->data_src_addr
[5];
300 ofld_req4
.src_mac_addr_lo
[1] = port
->data_src_addr
[4];
301 ofld_req4
.src_mac_addr_mid
[0] = port
->data_src_addr
[3];
302 ofld_req4
.src_mac_addr_mid
[1] = port
->data_src_addr
[2];
303 ofld_req4
.src_mac_addr_hi
[0] = port
->data_src_addr
[1];
304 ofld_req4
.src_mac_addr_hi
[1] = port
->data_src_addr
[0];
305 ofld_req4
.dst_mac_addr_lo
[0] = interface
->ctlr
.dest_addr
[5];
307 ofld_req4
.dst_mac_addr_lo
[1] = interface
->ctlr
.dest_addr
[4];
308 ofld_req4
.dst_mac_addr_mid
[0] = interface
->ctlr
.dest_addr
[3];
309 ofld_req4
.dst_mac_addr_mid
[1] = interface
->ctlr
.dest_addr
[2];
310 ofld_req4
.dst_mac_addr_hi
[0] = interface
->ctlr
.dest_addr
[1];
311 ofld_req4
.dst_mac_addr_hi
[1] = interface
->ctlr
.dest_addr
[0];
313 ofld_req4
.lcq_addr_lo
= (u32
) tgt
->lcq_dma
;
314 ofld_req4
.lcq_addr_hi
= (u32
)((u64
) tgt
->lcq_dma
>> 32);
316 ofld_req4
.confq_pbl_base_addr_lo
= (u32
) tgt
->confq_pbl_dma
;
317 ofld_req4
.confq_pbl_base_addr_hi
=
318 (u32
)((u64
) tgt
->confq_pbl_dma
>> 32);
320 kwqe_arr
[0] = (struct kwqe
*) &ofld_req1
;
321 kwqe_arr
[1] = (struct kwqe
*) &ofld_req2
;
322 kwqe_arr
[2] = (struct kwqe
*) &ofld_req3
;
323 kwqe_arr
[3] = (struct kwqe
*) &ofld_req4
;
325 if (hba
->cnic
&& hba
->cnic
->submit_kwqes
)
326 rc
= hba
->cnic
->submit_kwqes(hba
->cnic
, kwqe_arr
, num_kwqes
);
332 * bnx2fc_send_session_enable_req - initiates FCoE Session enablement
334 * @port: port structure pointer
335 * @tgt: bnx2fc_rport structure pointer
337 static int bnx2fc_send_session_enable_req(struct fcoe_port
*port
,
338 struct bnx2fc_rport
*tgt
)
340 struct kwqe
*kwqe_arr
[2];
341 struct bnx2fc_interface
*interface
= port
->priv
;
342 struct bnx2fc_hba
*hba
= interface
->hba
;
343 struct fcoe_kwqe_conn_enable_disable enbl_req
;
344 struct fc_lport
*lport
= port
->lport
;
345 struct fc_rport
*rport
= tgt
->rport
;
350 memset(&enbl_req
, 0x00,
351 sizeof(struct fcoe_kwqe_conn_enable_disable
));
352 enbl_req
.hdr
.op_code
= FCOE_KWQE_OPCODE_ENABLE_CONN
;
354 (FCOE_KWQE_LAYER_CODE
<< FCOE_KWQE_HEADER_LAYER_CODE_SHIFT
);
356 enbl_req
.src_mac_addr_lo
[0] = port
->data_src_addr
[5];
358 enbl_req
.src_mac_addr_lo
[1] = port
->data_src_addr
[4];
359 enbl_req
.src_mac_addr_mid
[0] = port
->data_src_addr
[3];
360 enbl_req
.src_mac_addr_mid
[1] = port
->data_src_addr
[2];
361 enbl_req
.src_mac_addr_hi
[0] = port
->data_src_addr
[1];
362 enbl_req
.src_mac_addr_hi
[1] = port
->data_src_addr
[0];
363 memcpy(tgt
->src_addr
, port
->data_src_addr
, ETH_ALEN
);
365 enbl_req
.dst_mac_addr_lo
[0] = interface
->ctlr
.dest_addr
[5];
366 enbl_req
.dst_mac_addr_lo
[1] = interface
->ctlr
.dest_addr
[4];
367 enbl_req
.dst_mac_addr_mid
[0] = interface
->ctlr
.dest_addr
[3];
368 enbl_req
.dst_mac_addr_mid
[1] = interface
->ctlr
.dest_addr
[2];
369 enbl_req
.dst_mac_addr_hi
[0] = interface
->ctlr
.dest_addr
[1];
370 enbl_req
.dst_mac_addr_hi
[1] = interface
->ctlr
.dest_addr
[0];
372 port_id
= fc_host_port_id(lport
->host
);
373 if (port_id
!= tgt
->sid
) {
374 printk(KERN_ERR PFX
"WARN: enable_req port_id = 0x%x,"
375 "sid = 0x%x\n", port_id
, tgt
->sid
);
378 enbl_req
.s_id
[0] = (port_id
& 0x000000FF);
379 enbl_req
.s_id
[1] = (port_id
& 0x0000FF00) >> 8;
380 enbl_req
.s_id
[2] = (port_id
& 0x00FF0000) >> 16;
382 port_id
= rport
->port_id
;
383 enbl_req
.d_id
[0] = (port_id
& 0x000000FF);
384 enbl_req
.d_id
[1] = (port_id
& 0x0000FF00) >> 8;
385 enbl_req
.d_id
[2] = (port_id
& 0x00FF0000) >> 16;
386 enbl_req
.vlan_tag
= interface
->vlan_id
<<
387 FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID_SHIFT
;
388 enbl_req
.vlan_tag
|= 3 << FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY_SHIFT
;
389 enbl_req
.vlan_flag
= interface
->vlan_enabled
;
390 enbl_req
.context_id
= tgt
->context_id
;
391 enbl_req
.conn_id
= tgt
->fcoe_conn_id
;
393 kwqe_arr
[0] = (struct kwqe
*) &enbl_req
;
395 if (hba
->cnic
&& hba
->cnic
->submit_kwqes
)
396 rc
= hba
->cnic
->submit_kwqes(hba
->cnic
, kwqe_arr
, num_kwqes
);
401 * bnx2fc_send_session_disable_req - initiates FCoE Session disable
403 * @port: port structure pointer
404 * @tgt: bnx2fc_rport structure pointer
406 int bnx2fc_send_session_disable_req(struct fcoe_port
*port
,
407 struct bnx2fc_rport
*tgt
)
409 struct bnx2fc_interface
*interface
= port
->priv
;
410 struct bnx2fc_hba
*hba
= interface
->hba
;
411 struct fcoe_kwqe_conn_enable_disable disable_req
;
412 struct kwqe
*kwqe_arr
[2];
413 struct fc_rport
*rport
= tgt
->rport
;
418 memset(&disable_req
, 0x00,
419 sizeof(struct fcoe_kwqe_conn_enable_disable
));
420 disable_req
.hdr
.op_code
= FCOE_KWQE_OPCODE_DISABLE_CONN
;
421 disable_req
.hdr
.flags
=
422 (FCOE_KWQE_LAYER_CODE
<< FCOE_KWQE_HEADER_LAYER_CODE_SHIFT
);
424 disable_req
.src_mac_addr_lo
[0] = tgt
->src_addr
[5];
425 disable_req
.src_mac_addr_lo
[1] = tgt
->src_addr
[4];
426 disable_req
.src_mac_addr_mid
[0] = tgt
->src_addr
[3];
427 disable_req
.src_mac_addr_mid
[1] = tgt
->src_addr
[2];
428 disable_req
.src_mac_addr_hi
[0] = tgt
->src_addr
[1];
429 disable_req
.src_mac_addr_hi
[1] = tgt
->src_addr
[0];
431 disable_req
.dst_mac_addr_lo
[0] = interface
->ctlr
.dest_addr
[5];
432 disable_req
.dst_mac_addr_lo
[1] = interface
->ctlr
.dest_addr
[4];
433 disable_req
.dst_mac_addr_mid
[0] = interface
->ctlr
.dest_addr
[3];
434 disable_req
.dst_mac_addr_mid
[1] = interface
->ctlr
.dest_addr
[2];
435 disable_req
.dst_mac_addr_hi
[0] = interface
->ctlr
.dest_addr
[1];
436 disable_req
.dst_mac_addr_hi
[1] = interface
->ctlr
.dest_addr
[0];
439 disable_req
.s_id
[0] = (port_id
& 0x000000FF);
440 disable_req
.s_id
[1] = (port_id
& 0x0000FF00) >> 8;
441 disable_req
.s_id
[2] = (port_id
& 0x00FF0000) >> 16;
444 port_id
= rport
->port_id
;
445 disable_req
.d_id
[0] = (port_id
& 0x000000FF);
446 disable_req
.d_id
[1] = (port_id
& 0x0000FF00) >> 8;
447 disable_req
.d_id
[2] = (port_id
& 0x00FF0000) >> 16;
448 disable_req
.context_id
= tgt
->context_id
;
449 disable_req
.conn_id
= tgt
->fcoe_conn_id
;
450 disable_req
.vlan_tag
= interface
->vlan_id
<<
451 FCOE_KWQE_CONN_ENABLE_DISABLE_VLAN_ID_SHIFT
;
452 disable_req
.vlan_tag
|=
453 3 << FCOE_KWQE_CONN_ENABLE_DISABLE_PRIORITY_SHIFT
;
454 disable_req
.vlan_flag
= interface
->vlan_enabled
;
456 kwqe_arr
[0] = (struct kwqe
*) &disable_req
;
458 if (hba
->cnic
&& hba
->cnic
->submit_kwqes
)
459 rc
= hba
->cnic
->submit_kwqes(hba
->cnic
, kwqe_arr
, num_kwqes
);
465 * bnx2fc_send_session_destroy_req - initiates FCoE Session destroy
467 * @port: port structure pointer
468 * @tgt: bnx2fc_rport structure pointer
470 int bnx2fc_send_session_destroy_req(struct bnx2fc_hba
*hba
,
471 struct bnx2fc_rport
*tgt
)
473 struct fcoe_kwqe_conn_destroy destroy_req
;
474 struct kwqe
*kwqe_arr
[2];
478 memset(&destroy_req
, 0x00, sizeof(struct fcoe_kwqe_conn_destroy
));
479 destroy_req
.hdr
.op_code
= FCOE_KWQE_OPCODE_DESTROY_CONN
;
480 destroy_req
.hdr
.flags
=
481 (FCOE_KWQE_LAYER_CODE
<< FCOE_KWQE_HEADER_LAYER_CODE_SHIFT
);
483 destroy_req
.context_id
= tgt
->context_id
;
484 destroy_req
.conn_id
= tgt
->fcoe_conn_id
;
486 kwqe_arr
[0] = (struct kwqe
*) &destroy_req
;
488 if (hba
->cnic
&& hba
->cnic
->submit_kwqes
)
489 rc
= hba
->cnic
->submit_kwqes(hba
->cnic
, kwqe_arr
, num_kwqes
);
494 static bool is_valid_lport(struct bnx2fc_hba
*hba
, struct fc_lport
*lport
)
496 struct bnx2fc_lport
*blport
;
498 spin_lock_bh(&hba
->hba_lock
);
499 list_for_each_entry(blport
, &hba
->vports
, list
) {
500 if (blport
->lport
== lport
) {
501 spin_unlock_bh(&hba
->hba_lock
);
505 spin_unlock_bh(&hba
->hba_lock
);
511 static void bnx2fc_unsol_els_work(struct work_struct
*work
)
513 struct bnx2fc_unsol_els
*unsol_els
;
514 struct fc_lport
*lport
;
515 struct bnx2fc_hba
*hba
;
518 unsol_els
= container_of(work
, struct bnx2fc_unsol_els
, unsol_els_work
);
519 lport
= unsol_els
->lport
;
521 hba
= unsol_els
->hba
;
522 if (is_valid_lport(hba
, lport
))
523 fc_exch_recv(lport
, fp
);
527 void bnx2fc_process_l2_frame_compl(struct bnx2fc_rport
*tgt
,
529 u32 frame_len
, u16 l2_oxid
)
531 struct fcoe_port
*port
= tgt
->port
;
532 struct fc_lport
*lport
= port
->lport
;
533 struct bnx2fc_interface
*interface
= port
->priv
;
534 struct bnx2fc_unsol_els
*unsol_els
;
535 struct fc_frame_header
*fh
;
543 unsol_els
= kzalloc(sizeof(*unsol_els
), GFP_ATOMIC
);
545 BNX2FC_TGT_DBG(tgt
, "Unable to allocate unsol_work\n");
549 BNX2FC_TGT_DBG(tgt
, "l2_frame_compl l2_oxid = 0x%x, frame_len = %d\n",
552 payload_len
= frame_len
- sizeof(struct fc_frame_header
);
554 fp
= fc_frame_alloc(lport
, payload_len
);
556 printk(KERN_ERR PFX
"fc_frame_alloc failure\n");
561 fh
= (struct fc_frame_header
*) fc_frame_header_get(fp
);
562 /* Copy FC Frame header and payload into the frame */
563 memcpy(fh
, buf
, frame_len
);
565 if (l2_oxid
!= FC_XID_UNKNOWN
)
566 fh
->fh_ox_id
= htons(l2_oxid
);
570 if ((fh
->fh_r_ctl
== FC_RCTL_ELS_REQ
) ||
571 (fh
->fh_r_ctl
== FC_RCTL_ELS_REP
)) {
573 if (fh
->fh_type
== FC_TYPE_ELS
) {
574 op
= fc_frame_payload_op(fp
);
575 if ((op
== ELS_TEST
) || (op
== ELS_ESTC
) ||
576 (op
== ELS_FAN
) || (op
== ELS_CSU
)) {
578 * No need to reply for these
581 printk(KERN_ERR PFX
"dropping ELS 0x%x\n", op
);
587 crc
= fcoe_fc_crc(fp
);
590 fr_sof(fp
) = FC_SOF_I3
;
591 fr_eof(fp
) = FC_EOF_T
;
592 fr_crc(fp
) = cpu_to_le32(~crc
);
593 unsol_els
->lport
= lport
;
594 unsol_els
->hba
= interface
->hba
;
596 INIT_WORK(&unsol_els
->unsol_els_work
, bnx2fc_unsol_els_work
);
597 queue_work(bnx2fc_wq
, &unsol_els
->unsol_els_work
);
599 BNX2FC_HBA_DBG(lport
, "fh_r_ctl = 0x%x\n", fh
->fh_r_ctl
);
605 static void bnx2fc_process_unsol_compl(struct bnx2fc_rport
*tgt
, u16 wqe
)
608 struct fcoe_err_report_entry
*err_entry
;
609 unsigned char *rq_data
;
610 unsigned char *buf
= NULL
, *buf1
;
614 struct bnx2fc_cmd
*io_req
= NULL
;
615 struct fcoe_task_ctx_entry
*task
, *task_page
;
616 struct bnx2fc_interface
*interface
= tgt
->port
->priv
;
617 struct bnx2fc_hba
*hba
= interface
->hba
;
622 BNX2FC_TGT_DBG(tgt
, "Entered UNSOL COMPLETION wqe = 0x%x\n", wqe
);
623 switch (wqe
& FCOE_UNSOLICITED_CQE_SUBTYPE
) {
624 case FCOE_UNSOLICITED_FRAME_CQE_TYPE
:
625 frame_len
= (wqe
& FCOE_UNSOLICITED_CQE_PKT_LEN
) >>
626 FCOE_UNSOLICITED_CQE_PKT_LEN_SHIFT
;
628 num_rq
= (frame_len
+ BNX2FC_RQ_BUF_SZ
- 1) / BNX2FC_RQ_BUF_SZ
;
630 spin_lock_bh(&tgt
->tgt_lock
);
631 rq_data
= (unsigned char *)bnx2fc_get_next_rqe(tgt
, num_rq
);
632 spin_unlock_bh(&tgt
->tgt_lock
);
637 buf1
= buf
= kmalloc((num_rq
* BNX2FC_RQ_BUF_SZ
),
641 BNX2FC_TGT_DBG(tgt
, "Memory alloc failure\n");
645 for (i
= 0; i
< num_rq
; i
++) {
646 spin_lock_bh(&tgt
->tgt_lock
);
647 rq_data
= (unsigned char *)
648 bnx2fc_get_next_rqe(tgt
, 1);
649 spin_unlock_bh(&tgt
->tgt_lock
);
650 len
= BNX2FC_RQ_BUF_SZ
;
651 memcpy(buf1
, rq_data
, len
);
655 bnx2fc_process_l2_frame_compl(tgt
, buf
, frame_len
,
660 spin_lock_bh(&tgt
->tgt_lock
);
661 bnx2fc_return_rqe(tgt
, num_rq
);
662 spin_unlock_bh(&tgt
->tgt_lock
);
665 case FCOE_ERROR_DETECTION_CQE_TYPE
:
667 * In case of error reporting CQE a single RQ entry
670 spin_lock_bh(&tgt
->tgt_lock
);
672 err_entry
= (struct fcoe_err_report_entry
*)
673 bnx2fc_get_next_rqe(tgt
, 1);
674 xid
= err_entry
->fc_hdr
.ox_id
;
675 BNX2FC_TGT_DBG(tgt
, "Unsol Error Frame OX_ID = 0x%x\n", xid
);
676 BNX2FC_TGT_DBG(tgt
, "err_warn_bitmap = %08x:%08x\n",
677 err_entry
->data
.err_warn_bitmap_hi
,
678 err_entry
->data
.err_warn_bitmap_lo
);
679 BNX2FC_TGT_DBG(tgt
, "buf_offsets - tx = 0x%x, rx = 0x%x\n",
680 err_entry
->data
.tx_buf_off
, err_entry
->data
.rx_buf_off
);
682 bnx2fc_return_rqe(tgt
, 1);
684 if (xid
> BNX2FC_MAX_XID
) {
685 BNX2FC_TGT_DBG(tgt
, "xid(0x%x) out of FW range\n",
687 spin_unlock_bh(&tgt
->tgt_lock
);
691 task_idx
= xid
/ BNX2FC_TASKS_PER_PAGE
;
692 index
= xid
% BNX2FC_TASKS_PER_PAGE
;
693 task_page
= (struct fcoe_task_ctx_entry
*)
694 hba
->task_ctx
[task_idx
];
695 task
= &(task_page
[index
]);
697 io_req
= (struct bnx2fc_cmd
*)hba
->cmd_mgr
->cmds
[xid
];
699 spin_unlock_bh(&tgt
->tgt_lock
);
703 if (io_req
->cmd_type
!= BNX2FC_SCSI_CMD
) {
704 printk(KERN_ERR PFX
"err_warn: Not a SCSI cmd\n");
705 spin_unlock_bh(&tgt
->tgt_lock
);
709 if (test_and_clear_bit(BNX2FC_FLAG_IO_CLEANUP
,
710 &io_req
->req_flags
)) {
711 BNX2FC_IO_DBG(io_req
, "unsol_err: cleanup in "
712 "progress.. ignore unsol err\n");
713 spin_unlock_bh(&tgt
->tgt_lock
);
718 * If ABTS is already in progress, and FW error is
719 * received after that, do not cancel the timeout_work
720 * and let the error recovery continue by explicitly
721 * logging out the target, when the ABTS eventually
724 if (!test_and_set_bit(BNX2FC_FLAG_ISSUE_ABTS
,
725 &io_req
->req_flags
)) {
727 * Cancel the timeout_work, as we received IO
728 * completion with FW error.
730 if (cancel_delayed_work(&io_req
->timeout_work
))
731 kref_put(&io_req
->refcount
,
732 bnx2fc_cmd_release
); /* timer hold */
734 rc
= bnx2fc_initiate_abts(io_req
);
736 BNX2FC_IO_DBG(io_req
, "err_warn: initiate_abts "
737 "failed. issue cleanup\n");
738 rc
= bnx2fc_initiate_cleanup(io_req
);
742 printk(KERN_ERR PFX
"err_warn: io_req (0x%x) already "
743 "in ABTS processing\n", xid
);
744 spin_unlock_bh(&tgt
->tgt_lock
);
747 case FCOE_WARNING_DETECTION_CQE_TYPE
:
749 *In case of warning reporting CQE a single RQ entry
752 spin_lock_bh(&tgt
->tgt_lock
);
754 err_entry
= (struct fcoe_err_report_entry
*)
755 bnx2fc_get_next_rqe(tgt
, 1);
756 xid
= cpu_to_be16(err_entry
->fc_hdr
.ox_id
);
757 BNX2FC_TGT_DBG(tgt
, "Unsol Warning Frame OX_ID = 0x%x\n", xid
);
758 BNX2FC_TGT_DBG(tgt
, "err_warn_bitmap = %08x:%08x",
759 err_entry
->data
.err_warn_bitmap_hi
,
760 err_entry
->data
.err_warn_bitmap_lo
);
761 BNX2FC_TGT_DBG(tgt
, "buf_offsets - tx = 0x%x, rx = 0x%x",
762 err_entry
->data
.tx_buf_off
, err_entry
->data
.rx_buf_off
);
764 bnx2fc_return_rqe(tgt
, 1);
765 spin_unlock_bh(&tgt
->tgt_lock
);
769 printk(KERN_ERR PFX
"Unsol Compl: Invalid CQE Subtype\n");
774 void bnx2fc_process_cq_compl(struct bnx2fc_rport
*tgt
, u16 wqe
)
776 struct fcoe_task_ctx_entry
*task
;
777 struct fcoe_task_ctx_entry
*task_page
;
778 struct fcoe_port
*port
= tgt
->port
;
779 struct bnx2fc_interface
*interface
= port
->priv
;
780 struct bnx2fc_hba
*hba
= interface
->hba
;
781 struct bnx2fc_cmd
*io_req
;
788 spin_lock_bh(&tgt
->tgt_lock
);
789 xid
= wqe
& FCOE_PEND_WQ_CQE_TASK_ID
;
790 if (xid
>= BNX2FC_MAX_TASKS
) {
791 printk(KERN_ERR PFX
"ERROR:xid out of range\n");
792 spin_unlock_bh(&tgt
->tgt_lock
);
795 task_idx
= xid
/ BNX2FC_TASKS_PER_PAGE
;
796 index
= xid
% BNX2FC_TASKS_PER_PAGE
;
797 task_page
= (struct fcoe_task_ctx_entry
*)hba
->task_ctx
[task_idx
];
798 task
= &(task_page
[index
]);
800 num_rq
= ((task
->rxwr_txrd
.var_ctx
.rx_flags
&
801 FCOE_TCE_RX_WR_TX_RD_VAR_NUM_RQ_WQE
) >>
802 FCOE_TCE_RX_WR_TX_RD_VAR_NUM_RQ_WQE_SHIFT
);
804 io_req
= (struct bnx2fc_cmd
*)hba
->cmd_mgr
->cmds
[xid
];
806 if (io_req
== NULL
) {
807 printk(KERN_ERR PFX
"ERROR? cq_compl - io_req is NULL\n");
808 spin_unlock_bh(&tgt
->tgt_lock
);
812 /* Timestamp IO completion time */
813 cmd_type
= io_req
->cmd_type
;
815 rx_state
= ((task
->rxwr_txrd
.var_ctx
.rx_flags
&
816 FCOE_TCE_RX_WR_TX_RD_VAR_RX_STATE
) >>
817 FCOE_TCE_RX_WR_TX_RD_VAR_RX_STATE_SHIFT
);
819 /* Process other IO completion types */
821 case BNX2FC_SCSI_CMD
:
822 if (rx_state
== FCOE_TASK_RX_STATE_COMPLETED
) {
823 bnx2fc_process_scsi_cmd_compl(io_req
, task
, num_rq
);
824 spin_unlock_bh(&tgt
->tgt_lock
);
828 if (rx_state
== FCOE_TASK_RX_STATE_ABTS_COMPLETED
)
829 bnx2fc_process_abts_compl(io_req
, task
, num_rq
);
831 FCOE_TASK_RX_STATE_EXCHANGE_CLEANUP_COMPLETED
)
832 bnx2fc_process_cleanup_compl(io_req
, task
, num_rq
);
834 printk(KERN_ERR PFX
"Invalid rx state - %d\n",
838 case BNX2FC_TASK_MGMT_CMD
:
839 BNX2FC_IO_DBG(io_req
, "Processing TM complete\n");
840 bnx2fc_process_tm_compl(io_req
, task
, num_rq
);
845 * ABTS request received by firmware. ABTS response
846 * will be delivered to the task belonging to the IO
849 BNX2FC_IO_DBG(io_req
, "cq_compl- ABTS sent out by fw\n");
850 kref_put(&io_req
->refcount
, bnx2fc_cmd_release
);
854 if (rx_state
== FCOE_TASK_RX_STATE_COMPLETED
)
855 bnx2fc_process_els_compl(io_req
, task
, num_rq
);
856 else if (rx_state
== FCOE_TASK_RX_STATE_ABTS_COMPLETED
)
857 bnx2fc_process_abts_compl(io_req
, task
, num_rq
);
859 FCOE_TASK_RX_STATE_EXCHANGE_CLEANUP_COMPLETED
)
860 bnx2fc_process_cleanup_compl(io_req
, task
, num_rq
);
862 printk(KERN_ERR PFX
"Invalid rx state = %d\n",
867 BNX2FC_IO_DBG(io_req
, "cq_compl- cleanup resp rcvd\n");
868 kref_put(&io_req
->refcount
, bnx2fc_cmd_release
);
872 printk(KERN_ERR PFX
"Invalid cmd_type %d\n", cmd_type
);
875 spin_unlock_bh(&tgt
->tgt_lock
);
878 void bnx2fc_arm_cq(struct bnx2fc_rport
*tgt
)
880 struct b577xx_fcoe_rx_doorbell
*rx_db
= &tgt
->rx_db
;
884 rx_db
->doorbell_cq_cons
= tgt
->cq_cons_idx
| (tgt
->cq_curr_toggle_bit
<<
885 FCOE_CQE_TOGGLE_BIT_SHIFT
);
886 msg
= *((u32
*)rx_db
);
887 writel(cpu_to_le32(msg
), tgt
->ctx_base
);
892 struct bnx2fc_work
*bnx2fc_alloc_work(struct bnx2fc_rport
*tgt
, u16 wqe
)
894 struct bnx2fc_work
*work
;
895 work
= kzalloc(sizeof(struct bnx2fc_work
), GFP_ATOMIC
);
899 INIT_LIST_HEAD(&work
->list
);
905 int bnx2fc_process_new_cqes(struct bnx2fc_rport
*tgt
)
909 struct fcoe_cqe
*cqe
;
910 u32 num_free_sqes
= 0;
914 * cq_lock is a low contention lock used to protect
915 * the CQ data structure from being freed up during
916 * the upload operation
918 spin_lock_bh(&tgt
->cq_lock
);
921 printk(KERN_ERR PFX
"process_new_cqes: cq is NULL\n");
922 spin_unlock_bh(&tgt
->cq_lock
);
926 cq_cons
= tgt
->cq_cons_idx
;
929 while (((wqe
= cqe
->wqe
) & FCOE_CQE_TOGGLE_BIT
) ==
930 (tgt
->cq_curr_toggle_bit
<<
931 FCOE_CQE_TOGGLE_BIT_SHIFT
)) {
933 /* new entry on the cq */
934 if (wqe
& FCOE_CQE_CQE_TYPE
) {
935 /* Unsolicited event notification */
936 bnx2fc_process_unsol_compl(tgt
, wqe
);
938 /* Pending work request completion */
939 struct bnx2fc_work
*work
= NULL
;
940 struct bnx2fc_percpu_s
*fps
= NULL
;
941 unsigned int cpu
= wqe
% num_possible_cpus();
943 fps
= &per_cpu(bnx2fc_percpu
, cpu
);
944 spin_lock_bh(&fps
->fp_work_lock
);
945 if (unlikely(!fps
->iothread
))
948 work
= bnx2fc_alloc_work(tgt
, wqe
);
950 list_add_tail(&work
->list
,
953 spin_unlock_bh(&fps
->fp_work_lock
);
955 /* Pending work request completion */
956 if (fps
->iothread
&& work
)
957 wake_up_process(fps
->iothread
);
959 bnx2fc_process_cq_compl(tgt
, wqe
);
965 if (tgt
->cq_cons_idx
== BNX2FC_CQ_WQES_MAX
) {
966 tgt
->cq_cons_idx
= 0;
968 tgt
->cq_curr_toggle_bit
=
969 1 - tgt
->cq_curr_toggle_bit
;
973 atomic_add(num_free_sqes
, &tgt
->free_sqes
);
974 spin_unlock_bh(&tgt
->cq_lock
);
979 * bnx2fc_fastpath_notification - process global event queue (KCQ)
981 * @hba: adapter structure pointer
982 * @new_cqe_kcqe: pointer to newly DMA'd KCQ entry
984 * Fast path event notification handler
986 static void bnx2fc_fastpath_notification(struct bnx2fc_hba
*hba
,
987 struct fcoe_kcqe
*new_cqe_kcqe
)
989 u32 conn_id
= new_cqe_kcqe
->fcoe_conn_id
;
990 struct bnx2fc_rport
*tgt
= hba
->tgt_ofld_list
[conn_id
];
993 printk(KERN_ERR PFX
"conn_id 0x%x not valid\n", conn_id
);
997 bnx2fc_process_new_cqes(tgt
);
1001 * bnx2fc_process_ofld_cmpl - process FCoE session offload completion
1003 * @hba: adapter structure pointer
1004 * @ofld_kcqe: connection offload kcqe pointer
1006 * handle session offload completion, enable the session if offload is
1009 static void bnx2fc_process_ofld_cmpl(struct bnx2fc_hba
*hba
,
1010 struct fcoe_kcqe
*ofld_kcqe
)
1012 struct bnx2fc_rport
*tgt
;
1013 struct fcoe_port
*port
;
1014 struct bnx2fc_interface
*interface
;
1019 conn_id
= ofld_kcqe
->fcoe_conn_id
;
1020 context_id
= ofld_kcqe
->fcoe_conn_context_id
;
1021 tgt
= hba
->tgt_ofld_list
[conn_id
];
1023 printk(KERN_ALERT PFX
"ERROR:ofld_cmpl: No pending ofld req\n");
1026 BNX2FC_TGT_DBG(tgt
, "Entered ofld compl - context_id = 0x%x\n",
1027 ofld_kcqe
->fcoe_conn_context_id
);
1029 interface
= tgt
->port
->priv
;
1030 if (hba
!= interface
->hba
) {
1031 printk(KERN_ERR PFX
"ERROR:ofld_cmpl: HBA mis-match\n");
1035 * cnic has allocated a context_id for this session; use this
1036 * while enabling the session.
1038 tgt
->context_id
= context_id
;
1039 if (ofld_kcqe
->completion_status
) {
1040 if (ofld_kcqe
->completion_status
==
1041 FCOE_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE
) {
1042 printk(KERN_ERR PFX
"unable to allocate FCoE context "
1044 set_bit(BNX2FC_FLAG_CTX_ALLOC_FAILURE
, &tgt
->flags
);
1049 /* now enable the session */
1050 rc
= bnx2fc_send_session_enable_req(port
, tgt
);
1052 printk(KERN_ERR PFX
"enable session failed\n");
1058 set_bit(BNX2FC_FLAG_OFLD_REQ_CMPL
, &tgt
->flags
);
1059 wake_up_interruptible(&tgt
->ofld_wait
);
1063 * bnx2fc_process_enable_conn_cmpl - process FCoE session enable completion
1065 * @hba: adapter structure pointer
1066 * @ofld_kcqe: connection offload kcqe pointer
1068 * handle session enable completion, mark the rport as ready
1071 static void bnx2fc_process_enable_conn_cmpl(struct bnx2fc_hba
*hba
,
1072 struct fcoe_kcqe
*ofld_kcqe
)
1074 struct bnx2fc_rport
*tgt
;
1075 struct bnx2fc_interface
*interface
;
1079 context_id
= ofld_kcqe
->fcoe_conn_context_id
;
1080 conn_id
= ofld_kcqe
->fcoe_conn_id
;
1081 tgt
= hba
->tgt_ofld_list
[conn_id
];
1083 printk(KERN_ERR PFX
"ERROR:enbl_cmpl: No pending ofld req\n");
1087 BNX2FC_TGT_DBG(tgt
, "Enable compl - context_id = 0x%x\n",
1088 ofld_kcqe
->fcoe_conn_context_id
);
1091 * context_id should be the same for this target during offload
1094 if (tgt
->context_id
!= context_id
) {
1095 printk(KERN_ERR PFX
"context id mis-match\n");
1098 interface
= tgt
->port
->priv
;
1099 if (hba
!= interface
->hba
) {
1100 printk(KERN_ERR PFX
"bnx2fc-enbl_cmpl: HBA mis-match\n");
1103 if (ofld_kcqe
->completion_status
)
1106 /* enable successful - rport ready for issuing IOs */
1107 set_bit(BNX2FC_FLAG_OFFLOADED
, &tgt
->flags
);
1108 set_bit(BNX2FC_FLAG_OFLD_REQ_CMPL
, &tgt
->flags
);
1109 wake_up_interruptible(&tgt
->ofld_wait
);
1114 set_bit(BNX2FC_FLAG_OFLD_REQ_CMPL
, &tgt
->flags
);
1115 wake_up_interruptible(&tgt
->ofld_wait
);
1118 static void bnx2fc_process_conn_disable_cmpl(struct bnx2fc_hba
*hba
,
1119 struct fcoe_kcqe
*disable_kcqe
)
1122 struct bnx2fc_rport
*tgt
;
1125 conn_id
= disable_kcqe
->fcoe_conn_id
;
1126 tgt
= hba
->tgt_ofld_list
[conn_id
];
1128 printk(KERN_ERR PFX
"ERROR: disable_cmpl: No disable req\n");
1132 BNX2FC_TGT_DBG(tgt
, PFX
"disable_cmpl: conn_id %d\n", conn_id
);
1134 if (disable_kcqe
->completion_status
) {
1135 printk(KERN_ERR PFX
"Disable failed with cmpl status %d\n",
1136 disable_kcqe
->completion_status
);
1139 /* disable successful */
1140 BNX2FC_TGT_DBG(tgt
, "disable successful\n");
1141 clear_bit(BNX2FC_FLAG_OFFLOADED
, &tgt
->flags
);
1142 set_bit(BNX2FC_FLAG_DISABLED
, &tgt
->flags
);
1143 set_bit(BNX2FC_FLAG_UPLD_REQ_COMPL
, &tgt
->flags
);
1144 wake_up_interruptible(&tgt
->upld_wait
);
1148 static void bnx2fc_process_conn_destroy_cmpl(struct bnx2fc_hba
*hba
,
1149 struct fcoe_kcqe
*destroy_kcqe
)
1151 struct bnx2fc_rport
*tgt
;
1154 conn_id
= destroy_kcqe
->fcoe_conn_id
;
1155 tgt
= hba
->tgt_ofld_list
[conn_id
];
1157 printk(KERN_ERR PFX
"destroy_cmpl: No destroy req\n");
1161 BNX2FC_TGT_DBG(tgt
, "destroy_cmpl: conn_id %d\n", conn_id
);
1163 if (destroy_kcqe
->completion_status
) {
1164 printk(KERN_ERR PFX
"Destroy conn failed, cmpl status %d\n",
1165 destroy_kcqe
->completion_status
);
1168 /* destroy successful */
1169 BNX2FC_TGT_DBG(tgt
, "upload successful\n");
1170 clear_bit(BNX2FC_FLAG_DISABLED
, &tgt
->flags
);
1171 set_bit(BNX2FC_FLAG_DESTROYED
, &tgt
->flags
);
1172 set_bit(BNX2FC_FLAG_UPLD_REQ_COMPL
, &tgt
->flags
);
1173 wake_up_interruptible(&tgt
->upld_wait
);
1177 static void bnx2fc_init_failure(struct bnx2fc_hba
*hba
, u32 err_code
)
1180 case FCOE_KCQE_COMPLETION_STATUS_INVALID_OPCODE
:
1181 printk(KERN_ERR PFX
"init_failure due to invalid opcode\n");
1184 case FCOE_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE
:
1185 printk(KERN_ERR PFX
"init failed due to ctx alloc failure\n");
1188 case FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR
:
1189 printk(KERN_ERR PFX
"init_failure due to NIC error\n");
1191 case FCOE_KCQE_COMPLETION_STATUS_ERROR
:
1192 printk(KERN_ERR PFX
"init failure due to compl status err\n");
1194 case FCOE_KCQE_COMPLETION_STATUS_WRONG_HSI_VERSION
:
1195 printk(KERN_ERR PFX
"init failure due to HSI mismatch\n");
1198 printk(KERN_ERR PFX
"Unknown Error code %d\n", err_code
);
1203 * bnx2fc_indicae_kcqe - process KCQE
1205 * @hba: adapter structure pointer
1206 * @kcqe: kcqe pointer
1207 * @num_cqe: Number of completion queue elements
1209 * Generic KCQ event handler
1211 void bnx2fc_indicate_kcqe(void *context
, struct kcqe
*kcq
[],
1214 struct bnx2fc_hba
*hba
= (struct bnx2fc_hba
*)context
;
1216 struct fcoe_kcqe
*kcqe
= NULL
;
1218 while (i
< num_cqe
) {
1219 kcqe
= (struct fcoe_kcqe
*) kcq
[i
++];
1221 switch (kcqe
->op_code
) {
1222 case FCOE_KCQE_OPCODE_CQ_EVENT_NOTIFICATION
:
1223 bnx2fc_fastpath_notification(hba
, kcqe
);
1226 case FCOE_KCQE_OPCODE_OFFLOAD_CONN
:
1227 bnx2fc_process_ofld_cmpl(hba
, kcqe
);
1230 case FCOE_KCQE_OPCODE_ENABLE_CONN
:
1231 bnx2fc_process_enable_conn_cmpl(hba
, kcqe
);
1234 case FCOE_KCQE_OPCODE_INIT_FUNC
:
1235 if (kcqe
->completion_status
!=
1236 FCOE_KCQE_COMPLETION_STATUS_SUCCESS
) {
1237 bnx2fc_init_failure(hba
,
1238 kcqe
->completion_status
);
1240 set_bit(ADAPTER_STATE_UP
, &hba
->adapter_state
);
1241 bnx2fc_get_link_state(hba
);
1242 printk(KERN_INFO PFX
"[%.2x]: FCOE_INIT passed\n",
1243 (u8
)hba
->pcidev
->bus
->number
);
1247 case FCOE_KCQE_OPCODE_DESTROY_FUNC
:
1248 if (kcqe
->completion_status
!=
1249 FCOE_KCQE_COMPLETION_STATUS_SUCCESS
) {
1251 printk(KERN_ERR PFX
"DESTROY failed\n");
1253 printk(KERN_ERR PFX
"DESTROY success\n");
1255 set_bit(BNX2FC_FLAG_DESTROY_CMPL
, &hba
->flags
);
1256 wake_up_interruptible(&hba
->destroy_wait
);
1259 case FCOE_KCQE_OPCODE_DISABLE_CONN
:
1260 bnx2fc_process_conn_disable_cmpl(hba
, kcqe
);
1263 case FCOE_KCQE_OPCODE_DESTROY_CONN
:
1264 bnx2fc_process_conn_destroy_cmpl(hba
, kcqe
);
1267 case FCOE_KCQE_OPCODE_STAT_FUNC
:
1268 if (kcqe
->completion_status
!=
1269 FCOE_KCQE_COMPLETION_STATUS_SUCCESS
)
1270 printk(KERN_ERR PFX
"STAT failed\n");
1271 complete(&hba
->stat_req_done
);
1274 case FCOE_KCQE_OPCODE_FCOE_ERROR
:
1277 printk(KERN_ERR PFX
"unknown opcode 0x%x\n",
1283 void bnx2fc_add_2_sq(struct bnx2fc_rport
*tgt
, u16 xid
)
1285 struct fcoe_sqe
*sqe
;
1287 sqe
= &tgt
->sq
[tgt
->sq_prod_idx
];
1290 sqe
->wqe
= xid
<< FCOE_SQE_TASK_ID_SHIFT
;
1291 sqe
->wqe
|= tgt
->sq_curr_toggle_bit
<< FCOE_SQE_TOGGLE_BIT_SHIFT
;
1293 /* Advance SQ Prod Idx */
1294 if (++tgt
->sq_prod_idx
== BNX2FC_SQ_WQES_MAX
) {
1295 tgt
->sq_prod_idx
= 0;
1296 tgt
->sq_curr_toggle_bit
= 1 - tgt
->sq_curr_toggle_bit
;
1300 void bnx2fc_ring_doorbell(struct bnx2fc_rport
*tgt
)
1302 struct b577xx_doorbell_set_prod
*sq_db
= &tgt
->sq_db
;
1306 sq_db
->prod
= tgt
->sq_prod_idx
|
1307 (tgt
->sq_curr_toggle_bit
<< 15);
1308 msg
= *((u32
*)sq_db
);
1309 writel(cpu_to_le32(msg
), tgt
->ctx_base
);
1314 int bnx2fc_map_doorbell(struct bnx2fc_rport
*tgt
)
1316 u32 context_id
= tgt
->context_id
;
1317 struct fcoe_port
*port
= tgt
->port
;
1319 resource_size_t reg_base
;
1320 struct bnx2fc_interface
*interface
= port
->priv
;
1321 struct bnx2fc_hba
*hba
= interface
->hba
;
1323 reg_base
= pci_resource_start(hba
->pcidev
,
1324 BNX2X_DOORBELL_PCI_BAR
);
1325 reg_off
= BNX2FC_5771X_DB_PAGE_SIZE
*
1326 (context_id
& 0x1FFFF) + DPM_TRIGER_TYPE
;
1327 tgt
->ctx_base
= ioremap_nocache(reg_base
+ reg_off
, 4);
1333 char *bnx2fc_get_next_rqe(struct bnx2fc_rport
*tgt
, u8 num_items
)
1335 char *buf
= (char *)tgt
->rq
+ (tgt
->rq_cons_idx
* BNX2FC_RQ_BUF_SZ
);
1337 if (tgt
->rq_cons_idx
+ num_items
> BNX2FC_RQ_WQES_MAX
)
1340 tgt
->rq_cons_idx
+= num_items
;
1342 if (tgt
->rq_cons_idx
>= BNX2FC_RQ_WQES_MAX
)
1343 tgt
->rq_cons_idx
-= BNX2FC_RQ_WQES_MAX
;
1348 void bnx2fc_return_rqe(struct bnx2fc_rport
*tgt
, u8 num_items
)
1350 /* return the rq buffer */
1351 u32 next_prod_idx
= tgt
->rq_prod_idx
+ num_items
;
1352 if ((next_prod_idx
& 0x7fff) == BNX2FC_RQ_WQES_MAX
) {
1353 /* Wrap around RQ */
1354 next_prod_idx
+= 0x8000 - BNX2FC_RQ_WQES_MAX
;
1356 tgt
->rq_prod_idx
= next_prod_idx
;
1357 tgt
->conn_db
->rq_prod
= tgt
->rq_prod_idx
;
1360 void bnx2fc_init_cleanup_task(struct bnx2fc_cmd
*io_req
,
1361 struct fcoe_task_ctx_entry
*task
,
1364 u8 task_type
= FCOE_TASK_TYPE_EXCHANGE_CLEANUP
;
1365 struct bnx2fc_rport
*tgt
= io_req
->tgt
;
1366 u32 context_id
= tgt
->context_id
;
1368 memset(task
, 0, sizeof(struct fcoe_task_ctx_entry
));
1370 /* Tx Write Rx Read */
1372 task
->txwr_rxrd
.const_ctx
.init_flags
= task_type
<<
1373 FCOE_TCE_TX_WR_RX_RD_CONST_TASK_TYPE_SHIFT
;
1374 task
->txwr_rxrd
.const_ctx
.init_flags
|= FCOE_TASK_CLASS_TYPE_3
<<
1375 FCOE_TCE_TX_WR_RX_RD_CONST_CLASS_TYPE_SHIFT
;
1376 task
->txwr_rxrd
.const_ctx
.init_flags
|=
1377 FCOE_TASK_DEV_TYPE_DISK
<<
1378 FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE_SHIFT
;
1379 task
->txwr_rxrd
.union_ctx
.cleanup
.ctx
.cleaned_task_id
= orig_xid
;
1382 task
->txwr_rxrd
.const_ctx
.tx_flags
=
1383 FCOE_TASK_TX_STATE_EXCHANGE_CLEANUP
<<
1384 FCOE_TCE_TX_WR_RX_RD_CONST_TX_STATE_SHIFT
;
1386 /* Rx Read Tx Write */
1387 task
->rxwr_txrd
.const_ctx
.init_flags
= context_id
<<
1388 FCOE_TCE_RX_WR_TX_RD_CONST_CID_SHIFT
;
1389 task
->rxwr_txrd
.var_ctx
.rx_flags
|= 1 <<
1390 FCOE_TCE_RX_WR_TX_RD_VAR_EXP_FIRST_FRAME_SHIFT
;
1393 void bnx2fc_init_mp_task(struct bnx2fc_cmd
*io_req
,
1394 struct fcoe_task_ctx_entry
*task
)
1396 struct bnx2fc_mp_req
*mp_req
= &(io_req
->mp_req
);
1397 struct bnx2fc_rport
*tgt
= io_req
->tgt
;
1398 struct fc_frame_header
*fc_hdr
;
1399 struct fcoe_ext_mul_sges_ctx
*sgl
;
1406 /* Obtain task_type */
1407 if ((io_req
->cmd_type
== BNX2FC_TASK_MGMT_CMD
) ||
1408 (io_req
->cmd_type
== BNX2FC_ELS
)) {
1409 task_type
= FCOE_TASK_TYPE_MIDPATH
;
1410 } else if (io_req
->cmd_type
== BNX2FC_ABTS
) {
1411 task_type
= FCOE_TASK_TYPE_ABTS
;
1414 memset(task
, 0, sizeof(struct fcoe_task_ctx_entry
));
1416 /* Setup the task from io_req for easy reference */
1417 io_req
->task
= task
;
1419 BNX2FC_IO_DBG(io_req
, "Init MP task for cmd_type = %d task_type = %d\n",
1420 io_req
->cmd_type
, task_type
);
1423 if ((task_type
== FCOE_TASK_TYPE_MIDPATH
) ||
1424 (task_type
== FCOE_TASK_TYPE_UNSOLICITED
)) {
1425 task
->txwr_only
.sgl_ctx
.sgl
.mul_sgl
.cur_sge_addr
.lo
=
1426 (u32
)mp_req
->mp_req_bd_dma
;
1427 task
->txwr_only
.sgl_ctx
.sgl
.mul_sgl
.cur_sge_addr
.hi
=
1428 (u32
)((u64
)mp_req
->mp_req_bd_dma
>> 32);
1429 task
->txwr_only
.sgl_ctx
.sgl
.mul_sgl
.sgl_size
= 1;
1432 /* Tx Write Rx Read */
1434 task
->txwr_rxrd
.const_ctx
.init_flags
= task_type
<<
1435 FCOE_TCE_TX_WR_RX_RD_CONST_TASK_TYPE_SHIFT
;
1436 task
->txwr_rxrd
.const_ctx
.init_flags
|=
1437 FCOE_TASK_DEV_TYPE_DISK
<<
1438 FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE_SHIFT
;
1439 task
->txwr_rxrd
.const_ctx
.init_flags
|= FCOE_TASK_CLASS_TYPE_3
<<
1440 FCOE_TCE_TX_WR_RX_RD_CONST_CLASS_TYPE_SHIFT
;
1443 task
->txwr_rxrd
.const_ctx
.tx_flags
= FCOE_TASK_TX_STATE_INIT
<<
1444 FCOE_TCE_TX_WR_RX_RD_CONST_TX_STATE_SHIFT
;
1446 /* Rx Write Tx Read */
1447 task
->rxwr_txrd
.const_ctx
.data_2_trns
= io_req
->data_xfer_len
;
1450 task
->rxwr_txrd
.var_ctx
.rx_flags
|= 1 <<
1451 FCOE_TCE_RX_WR_TX_RD_VAR_EXP_FIRST_FRAME_SHIFT
;
1453 context_id
= tgt
->context_id
;
1454 task
->rxwr_txrd
.const_ctx
.init_flags
= context_id
<<
1455 FCOE_TCE_RX_WR_TX_RD_CONST_CID_SHIFT
;
1457 fc_hdr
= &(mp_req
->req_fc_hdr
);
1458 if (task_type
== FCOE_TASK_TYPE_MIDPATH
) {
1459 fc_hdr
->fh_ox_id
= cpu_to_be16(io_req
->xid
);
1460 fc_hdr
->fh_rx_id
= htons(0xffff);
1461 task
->rxwr_txrd
.var_ctx
.rx_id
= 0xffff;
1462 } else if (task_type
== FCOE_TASK_TYPE_UNSOLICITED
) {
1463 fc_hdr
->fh_rx_id
= cpu_to_be16(io_req
->xid
);
1466 /* Fill FC Header into middle path buffer */
1467 hdr
= (u64
*) &task
->txwr_rxrd
.union_ctx
.tx_frame
.fc_hdr
;
1468 memcpy(temp_hdr
, fc_hdr
, sizeof(temp_hdr
));
1469 hdr
[0] = cpu_to_be64(temp_hdr
[0]);
1470 hdr
[1] = cpu_to_be64(temp_hdr
[1]);
1471 hdr
[2] = cpu_to_be64(temp_hdr
[2]);
1474 if (task_type
== FCOE_TASK_TYPE_MIDPATH
) {
1475 sgl
= &task
->rxwr_only
.union_ctx
.read_info
.sgl_ctx
.sgl
;
1477 sgl
->mul_sgl
.cur_sge_addr
.lo
= (u32
)mp_req
->mp_resp_bd_dma
;
1478 sgl
->mul_sgl
.cur_sge_addr
.hi
=
1479 (u32
)((u64
)mp_req
->mp_resp_bd_dma
>> 32);
1480 sgl
->mul_sgl
.sgl_size
= 1;
1484 void bnx2fc_init_task(struct bnx2fc_cmd
*io_req
,
1485 struct fcoe_task_ctx_entry
*task
)
1488 struct scsi_cmnd
*sc_cmd
= io_req
->sc_cmd
;
1489 struct io_bdt
*bd_tbl
= io_req
->bd_tbl
;
1490 struct bnx2fc_rport
*tgt
= io_req
->tgt
;
1491 struct fcoe_cached_sge_ctx
*cached_sge
;
1492 struct fcoe_ext_mul_sges_ctx
*sgl
;
1494 u64 tmp_fcp_cmnd
[4];
1499 memset(task
, 0, sizeof(struct fcoe_task_ctx_entry
));
1501 /* Setup the task from io_req for easy reference */
1502 io_req
->task
= task
;
1504 if (sc_cmd
->sc_data_direction
== DMA_TO_DEVICE
)
1505 task_type
= FCOE_TASK_TYPE_WRITE
;
1507 task_type
= FCOE_TASK_TYPE_READ
;
1510 if (task_type
== FCOE_TASK_TYPE_WRITE
) {
1511 task
->txwr_only
.sgl_ctx
.sgl
.mul_sgl
.cur_sge_addr
.lo
=
1512 (u32
)bd_tbl
->bd_tbl_dma
;
1513 task
->txwr_only
.sgl_ctx
.sgl
.mul_sgl
.cur_sge_addr
.hi
=
1514 (u32
)((u64
)bd_tbl
->bd_tbl_dma
>> 32);
1515 task
->txwr_only
.sgl_ctx
.sgl
.mul_sgl
.sgl_size
=
1519 /*Tx Write Rx Read */
1520 /* Init state to NORMAL */
1521 task
->txwr_rxrd
.const_ctx
.init_flags
= task_type
<<
1522 FCOE_TCE_TX_WR_RX_RD_CONST_TASK_TYPE_SHIFT
;
1523 task
->txwr_rxrd
.const_ctx
.init_flags
|=
1524 FCOE_TASK_DEV_TYPE_DISK
<<
1525 FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE_SHIFT
;
1526 task
->txwr_rxrd
.const_ctx
.init_flags
|= FCOE_TASK_CLASS_TYPE_3
<<
1527 FCOE_TCE_TX_WR_RX_RD_CONST_CLASS_TYPE_SHIFT
;
1529 task
->txwr_rxrd
.const_ctx
.tx_flags
= FCOE_TASK_TX_STATE_NORMAL
<<
1530 FCOE_TCE_TX_WR_RX_RD_CONST_TX_STATE_SHIFT
;
1532 /* Set initial seq counter */
1533 task
->txwr_rxrd
.union_ctx
.tx_seq
.ctx
.seq_cnt
= 1;
1535 /* Fill FCP_CMND IU */
1537 task
->txwr_rxrd
.union_ctx
.fcp_cmd
.opaque
;
1538 bnx2fc_build_fcp_cmnd(io_req
, (struct fcp_cmnd
*)&tmp_fcp_cmnd
);
1541 cnt
= sizeof(struct fcp_cmnd
) / sizeof(u64
);
1543 for (i
= 0; i
< cnt
; i
++) {
1544 *fcp_cmnd
= cpu_to_be64(tmp_fcp_cmnd
[i
]);
1548 /* Rx Write Tx Read */
1549 task
->rxwr_txrd
.const_ctx
.data_2_trns
= io_req
->data_xfer_len
;
1551 context_id
= tgt
->context_id
;
1552 task
->rxwr_txrd
.const_ctx
.init_flags
= context_id
<<
1553 FCOE_TCE_RX_WR_TX_RD_CONST_CID_SHIFT
;
1556 /* Set state to "waiting for the first packet" */
1557 task
->rxwr_txrd
.var_ctx
.rx_flags
|= 1 <<
1558 FCOE_TCE_RX_WR_TX_RD_VAR_EXP_FIRST_FRAME_SHIFT
;
1560 task
->rxwr_txrd
.var_ctx
.rx_id
= 0xffff;
1563 cached_sge
= &task
->rxwr_only
.union_ctx
.read_info
.sgl_ctx
.cached_sge
;
1564 sgl
= &task
->rxwr_only
.union_ctx
.read_info
.sgl_ctx
.sgl
;
1565 bd_count
= bd_tbl
->bd_valid
;
1566 if (task_type
== FCOE_TASK_TYPE_READ
) {
1567 if (bd_count
== 1) {
1569 struct fcoe_bd_ctx
*fcoe_bd_tbl
= bd_tbl
->bd_tbl
;
1571 cached_sge
->cur_buf_addr
.lo
= fcoe_bd_tbl
->buf_addr_lo
;
1572 cached_sge
->cur_buf_addr
.hi
= fcoe_bd_tbl
->buf_addr_hi
;
1573 cached_sge
->cur_buf_rem
= fcoe_bd_tbl
->buf_len
;
1574 task
->txwr_rxrd
.const_ctx
.init_flags
|= 1 <<
1575 FCOE_TCE_TX_WR_RX_RD_CONST_CACHED_SGE_SHIFT
;
1576 } else if (bd_count
== 2) {
1577 struct fcoe_bd_ctx
*fcoe_bd_tbl
= bd_tbl
->bd_tbl
;
1579 cached_sge
->cur_buf_addr
.lo
= fcoe_bd_tbl
->buf_addr_lo
;
1580 cached_sge
->cur_buf_addr
.hi
= fcoe_bd_tbl
->buf_addr_hi
;
1581 cached_sge
->cur_buf_rem
= fcoe_bd_tbl
->buf_len
;
1584 cached_sge
->second_buf_addr
.lo
=
1585 fcoe_bd_tbl
->buf_addr_lo
;
1586 cached_sge
->second_buf_addr
.hi
=
1587 fcoe_bd_tbl
->buf_addr_hi
;
1588 cached_sge
->second_buf_rem
= fcoe_bd_tbl
->buf_len
;
1589 task
->txwr_rxrd
.const_ctx
.init_flags
|= 1 <<
1590 FCOE_TCE_TX_WR_RX_RD_CONST_CACHED_SGE_SHIFT
;
1593 sgl
->mul_sgl
.cur_sge_addr
.lo
= (u32
)bd_tbl
->bd_tbl_dma
;
1594 sgl
->mul_sgl
.cur_sge_addr
.hi
=
1595 (u32
)((u64
)bd_tbl
->bd_tbl_dma
>> 32);
1596 sgl
->mul_sgl
.sgl_size
= bd_count
;
1602 * bnx2fc_setup_task_ctx - allocate and map task context
1604 * @hba: pointer to adapter structure
1606 * allocate memory for task context, and associated BD table to be used
1610 int bnx2fc_setup_task_ctx(struct bnx2fc_hba
*hba
)
1613 struct regpair
*task_ctx_bdt
;
1618 * Allocate task context bd table. A page size of bd table
1619 * can map 256 buffers. Each buffer contains 32 task context
1620 * entries. Hence the limit with one page is 8192 task context
1623 hba
->task_ctx_bd_tbl
= dma_alloc_coherent(&hba
->pcidev
->dev
,
1625 &hba
->task_ctx_bd_dma
,
1627 if (!hba
->task_ctx_bd_tbl
) {
1628 printk(KERN_ERR PFX
"unable to allocate task context BDT\n");
1632 memset(hba
->task_ctx_bd_tbl
, 0, PAGE_SIZE
);
1635 * Allocate task_ctx which is an array of pointers pointing to
1636 * a page containing 32 task contexts
1638 hba
->task_ctx
= kzalloc((BNX2FC_TASK_CTX_ARR_SZ
* sizeof(void *)),
1640 if (!hba
->task_ctx
) {
1641 printk(KERN_ERR PFX
"unable to allocate task context array\n");
1647 * Allocate task_ctx_dma which is an array of dma addresses
1649 hba
->task_ctx_dma
= kmalloc((BNX2FC_TASK_CTX_ARR_SZ
*
1650 sizeof(dma_addr_t
)), GFP_KERNEL
);
1651 if (!hba
->task_ctx_dma
) {
1652 printk(KERN_ERR PFX
"unable to alloc context mapping array\n");
1657 task_ctx_bdt
= (struct regpair
*)hba
->task_ctx_bd_tbl
;
1658 for (i
= 0; i
< BNX2FC_TASK_CTX_ARR_SZ
; i
++) {
1660 hba
->task_ctx
[i
] = dma_alloc_coherent(&hba
->pcidev
->dev
,
1662 &hba
->task_ctx_dma
[i
],
1664 if (!hba
->task_ctx
[i
]) {
1665 printk(KERN_ERR PFX
"unable to alloc task context\n");
1669 memset(hba
->task_ctx
[i
], 0, PAGE_SIZE
);
1670 addr
= (u64
)hba
->task_ctx_dma
[i
];
1671 task_ctx_bdt
->hi
= cpu_to_le32((u64
)addr
>> 32);
1672 task_ctx_bdt
->lo
= cpu_to_le32((u32
)addr
);
1678 for (i
= 0; i
< BNX2FC_TASK_CTX_ARR_SZ
; i
++) {
1679 if (hba
->task_ctx
[i
]) {
1681 dma_free_coherent(&hba
->pcidev
->dev
, PAGE_SIZE
,
1682 hba
->task_ctx
[i
], hba
->task_ctx_dma
[i
]);
1683 hba
->task_ctx
[i
] = NULL
;
1687 kfree(hba
->task_ctx_dma
);
1688 hba
->task_ctx_dma
= NULL
;
1690 kfree(hba
->task_ctx
);
1691 hba
->task_ctx
= NULL
;
1693 dma_free_coherent(&hba
->pcidev
->dev
, PAGE_SIZE
,
1694 hba
->task_ctx_bd_tbl
, hba
->task_ctx_bd_dma
);
1695 hba
->task_ctx_bd_tbl
= NULL
;
1700 void bnx2fc_free_task_ctx(struct bnx2fc_hba
*hba
)
1704 if (hba
->task_ctx_bd_tbl
) {
1705 dma_free_coherent(&hba
->pcidev
->dev
, PAGE_SIZE
,
1706 hba
->task_ctx_bd_tbl
,
1707 hba
->task_ctx_bd_dma
);
1708 hba
->task_ctx_bd_tbl
= NULL
;
1711 if (hba
->task_ctx
) {
1712 for (i
= 0; i
< BNX2FC_TASK_CTX_ARR_SZ
; i
++) {
1713 if (hba
->task_ctx
[i
]) {
1714 dma_free_coherent(&hba
->pcidev
->dev
, PAGE_SIZE
,
1716 hba
->task_ctx_dma
[i
]);
1717 hba
->task_ctx
[i
] = NULL
;
1720 kfree(hba
->task_ctx
);
1721 hba
->task_ctx
= NULL
;
1724 kfree(hba
->task_ctx_dma
);
1725 hba
->task_ctx_dma
= NULL
;
1728 static void bnx2fc_free_hash_table(struct bnx2fc_hba
*hba
)
1732 int hash_table_size
;
1735 segment_count
= hba
->hash_tbl_segment_count
;
1736 hash_table_size
= BNX2FC_NUM_MAX_SESS
* BNX2FC_MAX_ROWS_IN_HASH_TBL
*
1737 sizeof(struct fcoe_hash_table_entry
);
1739 pbl
= hba
->hash_tbl_pbl
;
1740 for (i
= 0; i
< segment_count
; ++i
) {
1741 dma_addr_t dma_address
;
1743 dma_address
= le32_to_cpu(*pbl
);
1745 dma_address
+= ((u64
)le32_to_cpu(*pbl
)) << 32;
1747 dma_free_coherent(&hba
->pcidev
->dev
,
1748 BNX2FC_HASH_TBL_CHUNK_SIZE
,
1749 hba
->hash_tbl_segments
[i
],
1754 if (hba
->hash_tbl_pbl
) {
1755 dma_free_coherent(&hba
->pcidev
->dev
, PAGE_SIZE
,
1757 hba
->hash_tbl_pbl_dma
);
1758 hba
->hash_tbl_pbl
= NULL
;
1762 static int bnx2fc_allocate_hash_table(struct bnx2fc_hba
*hba
)
1765 int hash_table_size
;
1767 int segment_array_size
;
1768 int dma_segment_array_size
;
1769 dma_addr_t
*dma_segment_array
;
1772 hash_table_size
= BNX2FC_NUM_MAX_SESS
* BNX2FC_MAX_ROWS_IN_HASH_TBL
*
1773 sizeof(struct fcoe_hash_table_entry
);
1775 segment_count
= hash_table_size
+ BNX2FC_HASH_TBL_CHUNK_SIZE
- 1;
1776 segment_count
/= BNX2FC_HASH_TBL_CHUNK_SIZE
;
1777 hba
->hash_tbl_segment_count
= segment_count
;
1779 segment_array_size
= segment_count
* sizeof(*hba
->hash_tbl_segments
);
1780 hba
->hash_tbl_segments
= kzalloc(segment_array_size
, GFP_KERNEL
);
1781 if (!hba
->hash_tbl_segments
) {
1782 printk(KERN_ERR PFX
"hash table pointers alloc failed\n");
1785 dma_segment_array_size
= segment_count
* sizeof(*dma_segment_array
);
1786 dma_segment_array
= kzalloc(dma_segment_array_size
, GFP_KERNEL
);
1787 if (!dma_segment_array
) {
1788 printk(KERN_ERR PFX
"hash table pointers (dma) alloc failed\n");
1792 for (i
= 0; i
< segment_count
; ++i
) {
1793 hba
->hash_tbl_segments
[i
] =
1794 dma_alloc_coherent(&hba
->pcidev
->dev
,
1795 BNX2FC_HASH_TBL_CHUNK_SIZE
,
1796 &dma_segment_array
[i
],
1798 if (!hba
->hash_tbl_segments
[i
]) {
1799 printk(KERN_ERR PFX
"hash segment alloc failed\n");
1801 dma_free_coherent(&hba
->pcidev
->dev
,
1802 BNX2FC_HASH_TBL_CHUNK_SIZE
,
1803 hba
->hash_tbl_segments
[i
],
1804 dma_segment_array
[i
]);
1805 hba
->hash_tbl_segments
[i
] = NULL
;
1807 kfree(dma_segment_array
);
1810 memset(hba
->hash_tbl_segments
[i
], 0,
1811 BNX2FC_HASH_TBL_CHUNK_SIZE
);
1814 hba
->hash_tbl_pbl
= dma_alloc_coherent(&hba
->pcidev
->dev
,
1816 &hba
->hash_tbl_pbl_dma
,
1818 if (!hba
->hash_tbl_pbl
) {
1819 printk(KERN_ERR PFX
"hash table pbl alloc failed\n");
1820 kfree(dma_segment_array
);
1823 memset(hba
->hash_tbl_pbl
, 0, PAGE_SIZE
);
1825 pbl
= hba
->hash_tbl_pbl
;
1826 for (i
= 0; i
< segment_count
; ++i
) {
1827 u64 paddr
= dma_segment_array
[i
];
1828 *pbl
= cpu_to_le32((u32
) paddr
);
1830 *pbl
= cpu_to_le32((u32
) (paddr
>> 32));
1833 pbl
= hba
->hash_tbl_pbl
;
1835 while (*pbl
&& *(pbl
+ 1)) {
1844 kfree(dma_segment_array
);
1849 * bnx2fc_setup_fw_resc - Allocate and map hash table and dummy buffer
1851 * @hba: Pointer to adapter structure
1854 int bnx2fc_setup_fw_resc(struct bnx2fc_hba
*hba
)
1860 if (bnx2fc_allocate_hash_table(hba
))
1863 mem_size
= BNX2FC_NUM_MAX_SESS
* sizeof(struct regpair
);
1864 hba
->t2_hash_tbl_ptr
= dma_alloc_coherent(&hba
->pcidev
->dev
, mem_size
,
1865 &hba
->t2_hash_tbl_ptr_dma
,
1867 if (!hba
->t2_hash_tbl_ptr
) {
1868 printk(KERN_ERR PFX
"unable to allocate t2 hash table ptr\n");
1869 bnx2fc_free_fw_resc(hba
);
1872 memset(hba
->t2_hash_tbl_ptr
, 0x00, mem_size
);
1874 mem_size
= BNX2FC_NUM_MAX_SESS
*
1875 sizeof(struct fcoe_t2_hash_table_entry
);
1876 hba
->t2_hash_tbl
= dma_alloc_coherent(&hba
->pcidev
->dev
, mem_size
,
1877 &hba
->t2_hash_tbl_dma
,
1879 if (!hba
->t2_hash_tbl
) {
1880 printk(KERN_ERR PFX
"unable to allocate t2 hash table\n");
1881 bnx2fc_free_fw_resc(hba
);
1884 memset(hba
->t2_hash_tbl
, 0x00, mem_size
);
1885 for (i
= 0; i
< BNX2FC_NUM_MAX_SESS
; i
++) {
1886 addr
= (unsigned long) hba
->t2_hash_tbl_dma
+
1887 ((i
+1) * sizeof(struct fcoe_t2_hash_table_entry
));
1888 hba
->t2_hash_tbl
[i
].next
.lo
= addr
& 0xffffffff;
1889 hba
->t2_hash_tbl
[i
].next
.hi
= addr
>> 32;
1892 hba
->dummy_buffer
= dma_alloc_coherent(&hba
->pcidev
->dev
,
1893 PAGE_SIZE
, &hba
->dummy_buf_dma
,
1895 if (!hba
->dummy_buffer
) {
1896 printk(KERN_ERR PFX
"unable to alloc MP Dummy Buffer\n");
1897 bnx2fc_free_fw_resc(hba
);
1901 hba
->stats_buffer
= dma_alloc_coherent(&hba
->pcidev
->dev
,
1903 &hba
->stats_buf_dma
,
1905 if (!hba
->stats_buffer
) {
1906 printk(KERN_ERR PFX
"unable to alloc Stats Buffer\n");
1907 bnx2fc_free_fw_resc(hba
);
1910 memset(hba
->stats_buffer
, 0x00, PAGE_SIZE
);
1915 void bnx2fc_free_fw_resc(struct bnx2fc_hba
*hba
)
1919 if (hba
->stats_buffer
) {
1920 dma_free_coherent(&hba
->pcidev
->dev
, PAGE_SIZE
,
1921 hba
->stats_buffer
, hba
->stats_buf_dma
);
1922 hba
->stats_buffer
= NULL
;
1925 if (hba
->dummy_buffer
) {
1926 dma_free_coherent(&hba
->pcidev
->dev
, PAGE_SIZE
,
1927 hba
->dummy_buffer
, hba
->dummy_buf_dma
);
1928 hba
->dummy_buffer
= NULL
;
1931 if (hba
->t2_hash_tbl_ptr
) {
1932 mem_size
= BNX2FC_NUM_MAX_SESS
* sizeof(struct regpair
);
1933 dma_free_coherent(&hba
->pcidev
->dev
, mem_size
,
1934 hba
->t2_hash_tbl_ptr
,
1935 hba
->t2_hash_tbl_ptr_dma
);
1936 hba
->t2_hash_tbl_ptr
= NULL
;
1939 if (hba
->t2_hash_tbl
) {
1940 mem_size
= BNX2FC_NUM_MAX_SESS
*
1941 sizeof(struct fcoe_t2_hash_table_entry
);
1942 dma_free_coherent(&hba
->pcidev
->dev
, mem_size
,
1943 hba
->t2_hash_tbl
, hba
->t2_hash_tbl_dma
);
1944 hba
->t2_hash_tbl
= NULL
;
1946 bnx2fc_free_hash_table(hba
);