1 /* bnx2fc_tgt.c: Broadcom NetXtreme II Linux FCoE offload driver.
2 * Handles operations such as session offload/upload etc, and manages
3 * session resources such as connection id and qp resources.
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)
15 static void bnx2fc_upld_timer(unsigned long data
);
16 static void bnx2fc_ofld_timer(unsigned long data
);
17 static int bnx2fc_init_tgt(struct bnx2fc_rport
*tgt
,
18 struct fcoe_port
*port
,
19 struct fc_rport_priv
*rdata
);
20 static u32
bnx2fc_alloc_conn_id(struct bnx2fc_hba
*hba
,
21 struct bnx2fc_rport
*tgt
);
22 static int bnx2fc_alloc_session_resc(struct bnx2fc_hba
*hba
,
23 struct bnx2fc_rport
*tgt
);
24 static void bnx2fc_free_session_resc(struct bnx2fc_hba
*hba
,
25 struct bnx2fc_rport
*tgt
);
26 static void bnx2fc_free_conn_id(struct bnx2fc_hba
*hba
, u32 conn_id
);
28 static void bnx2fc_upld_timer(unsigned long data
)
31 struct bnx2fc_rport
*tgt
= (struct bnx2fc_rport
*)data
;
33 BNX2FC_TGT_DBG(tgt
, "upld_timer - Upload compl not received!!\n");
34 /* fake upload completion */
35 clear_bit(BNX2FC_FLAG_OFFLOADED
, &tgt
->flags
);
36 set_bit(BNX2FC_FLAG_UPLD_REQ_COMPL
, &tgt
->flags
);
37 wake_up_interruptible(&tgt
->upld_wait
);
40 static void bnx2fc_ofld_timer(unsigned long data
)
43 struct bnx2fc_rport
*tgt
= (struct bnx2fc_rport
*)data
;
45 BNX2FC_TGT_DBG(tgt
, "entered bnx2fc_ofld_timer\n");
46 /* NOTE: This function should never be called, as
47 * offload should never timeout
50 * If the timer has expired, this session is dead
51 * Clear offloaded flag and logout of this device.
52 * Since OFFLOADED flag is cleared, this case
53 * will be considered as offload error and the
54 * port will be logged off, and conn_id, session
55 * resources are freed up in bnx2fc_offload_session
57 clear_bit(BNX2FC_FLAG_OFFLOADED
, &tgt
->flags
);
58 set_bit(BNX2FC_FLAG_OFLD_REQ_CMPL
, &tgt
->flags
);
59 wake_up_interruptible(&tgt
->ofld_wait
);
62 static void bnx2fc_offload_session(struct fcoe_port
*port
,
63 struct bnx2fc_rport
*tgt
,
64 struct fc_rport_priv
*rdata
)
66 struct fc_lport
*lport
= rdata
->local_port
;
67 struct fc_rport
*rport
= rdata
->rport
;
68 struct bnx2fc_hba
*hba
= port
->priv
;
72 /* Initialize bnx2fc_rport */
73 /* NOTE: tgt is already bzero'd */
74 rval
= bnx2fc_init_tgt(tgt
, port
, rdata
);
76 printk(KERN_ERR PFX
"Failed to allocate conn id for "
77 "port_id (%6x)\n", rport
->port_id
);
81 /* Allocate session resources */
82 rval
= bnx2fc_alloc_session_resc(hba
, tgt
);
84 printk(KERN_ERR PFX
"Failed to allocate resources\n");
89 * Initialize FCoE session offload process.
90 * Upon completion of offload process add
91 * rport to list of rports
94 clear_bit(BNX2FC_FLAG_OFLD_REQ_CMPL
, &tgt
->flags
);
95 rval
= bnx2fc_send_session_ofld_req(port
, tgt
);
97 printk(KERN_ERR PFX
"ofld_req failed\n");
102 * wait for the session is offloaded and enabled. 3 Secs
103 * should be ample time for this process to complete.
105 setup_timer(&tgt
->ofld_timer
, bnx2fc_ofld_timer
, (unsigned long)tgt
);
106 mod_timer(&tgt
->ofld_timer
, jiffies
+ BNX2FC_FW_TIMEOUT
);
108 wait_event_interruptible(tgt
->ofld_wait
,
110 BNX2FC_FLAG_OFLD_REQ_CMPL
,
112 if (signal_pending(current
))
113 flush_signals(current
);
115 del_timer_sync(&tgt
->ofld_timer
);
117 if (!(test_bit(BNX2FC_FLAG_OFFLOADED
, &tgt
->flags
))) {
118 if (test_and_clear_bit(BNX2FC_FLAG_CTX_ALLOC_FAILURE
,
120 BNX2FC_TGT_DBG(tgt
, "ctx_alloc_failure, "
121 "retry ofld..%d\n", i
++);
122 msleep_interruptible(1000);
131 if (bnx2fc_map_doorbell(tgt
)) {
132 printk(KERN_ERR PFX
"map doorbell failed - no mem\n");
133 /* upload will take care of cleaning up sess resc */
134 lport
->tt
.rport_logoff(rdata
);
139 /* couldn't offload the session. log off from this rport */
140 BNX2FC_TGT_DBG(tgt
, "bnx2fc_offload_session - offload error\n");
141 lport
->tt
.rport_logoff(rdata
);
142 /* Free session resources */
143 bnx2fc_free_session_resc(hba
, tgt
);
144 if (tgt
->fcoe_conn_id
!= -1)
145 bnx2fc_free_conn_id(hba
, tgt
->fcoe_conn_id
);
148 void bnx2fc_flush_active_ios(struct bnx2fc_rport
*tgt
)
150 struct bnx2fc_cmd
*io_req
;
151 struct list_head
*list
;
152 struct list_head
*tmp
;
155 BNX2FC_TGT_DBG(tgt
, "Entered flush_active_ios - %d\n",
156 tgt
->num_active_ios
.counter
);
158 spin_lock_bh(&tgt
->tgt_lock
);
159 tgt
->flush_in_prog
= 1;
161 list_for_each_safe(list
, tmp
, &tgt
->active_cmd_queue
) {
163 io_req
= (struct bnx2fc_cmd
*)list
;
164 list_del_init(&io_req
->link
);
165 io_req
->on_active_queue
= 0;
166 BNX2FC_IO_DBG(io_req
, "cmd_queue cleanup\n");
168 if (cancel_delayed_work(&io_req
->timeout_work
)) {
169 if (test_and_clear_bit(BNX2FC_FLAG_EH_ABORT
,
170 &io_req
->req_flags
)) {
171 /* Handle eh_abort timeout */
172 BNX2FC_IO_DBG(io_req
, "eh_abort for IO "
174 complete(&io_req
->tm_done
);
176 kref_put(&io_req
->refcount
,
177 bnx2fc_cmd_release
); /* drop timer hold */
180 set_bit(BNX2FC_FLAG_IO_COMPL
, &io_req
->req_flags
);
181 set_bit(BNX2FC_FLAG_IO_CLEANUP
, &io_req
->req_flags
);
182 rc
= bnx2fc_initiate_cleanup(io_req
);
186 list_for_each_safe(list
, tmp
, &tgt
->els_queue
) {
188 io_req
= (struct bnx2fc_cmd
*)list
;
189 list_del_init(&io_req
->link
);
190 io_req
->on_active_queue
= 0;
192 BNX2FC_IO_DBG(io_req
, "els_queue cleanup\n");
194 if (cancel_delayed_work(&io_req
->timeout_work
))
195 kref_put(&io_req
->refcount
,
196 bnx2fc_cmd_release
); /* drop timer hold */
198 if ((io_req
->cb_func
) && (io_req
->cb_arg
)) {
199 io_req
->cb_func(io_req
->cb_arg
);
200 io_req
->cb_arg
= NULL
;
203 rc
= bnx2fc_initiate_cleanup(io_req
);
207 list_for_each_safe(list
, tmp
, &tgt
->io_retire_queue
) {
209 io_req
= (struct bnx2fc_cmd
*)list
;
210 list_del_init(&io_req
->link
);
212 BNX2FC_IO_DBG(io_req
, "retire_queue flush\n");
214 if (cancel_delayed_work(&io_req
->timeout_work
))
215 kref_put(&io_req
->refcount
, bnx2fc_cmd_release
);
217 clear_bit(BNX2FC_FLAG_ISSUE_RRQ
, &io_req
->req_flags
);
220 BNX2FC_TGT_DBG(tgt
, "IOs flushed = %d\n", i
);
222 spin_unlock_bh(&tgt
->tgt_lock
);
223 /* wait for active_ios to go to 0 */
224 while ((tgt
->num_active_ios
.counter
!= 0) && (i
++ < BNX2FC_WAIT_CNT
))
226 if (tgt
->num_active_ios
.counter
!= 0)
227 printk(KERN_ERR PFX
"CLEANUP on port 0x%x:"
228 " active_ios = %d\n",
229 tgt
->rdata
->ids
.port_id
, tgt
->num_active_ios
.counter
);
230 spin_lock_bh(&tgt
->tgt_lock
);
231 tgt
->flush_in_prog
= 0;
232 spin_unlock_bh(&tgt
->tgt_lock
);
235 static void bnx2fc_upload_session(struct fcoe_port
*port
,
236 struct bnx2fc_rport
*tgt
)
238 struct bnx2fc_hba
*hba
= port
->priv
;
240 BNX2FC_TGT_DBG(tgt
, "upload_session: active_ios = %d\n",
241 tgt
->num_active_ios
.counter
);
244 * Called with hba->hba_mutex held.
245 * This is a blocking call
247 clear_bit(BNX2FC_FLAG_UPLD_REQ_COMPL
, &tgt
->flags
);
248 bnx2fc_send_session_disable_req(port
, tgt
);
251 * wait for upload to complete. 3 Secs
252 * should be sufficient time for this process to complete.
254 setup_timer(&tgt
->upld_timer
, bnx2fc_upld_timer
, (unsigned long)tgt
);
255 mod_timer(&tgt
->upld_timer
, jiffies
+ BNX2FC_FW_TIMEOUT
);
257 BNX2FC_TGT_DBG(tgt
, "waiting for disable compl\n");
258 wait_event_interruptible(tgt
->upld_wait
,
260 BNX2FC_FLAG_UPLD_REQ_COMPL
,
263 if (signal_pending(current
))
264 flush_signals(current
);
266 del_timer_sync(&tgt
->upld_timer
);
269 * traverse thru the active_q and tmf_q and cleanup
272 BNX2FC_TGT_DBG(tgt
, "flush/upload - disable wait flags = 0x%lx\n",
274 bnx2fc_flush_active_ios(tgt
);
276 /* Issue destroy KWQE */
277 if (test_bit(BNX2FC_FLAG_DISABLED
, &tgt
->flags
)) {
278 BNX2FC_TGT_DBG(tgt
, "send destroy req\n");
279 clear_bit(BNX2FC_FLAG_UPLD_REQ_COMPL
, &tgt
->flags
);
280 bnx2fc_send_session_destroy_req(hba
, tgt
);
282 /* wait for destroy to complete */
283 setup_timer(&tgt
->upld_timer
,
284 bnx2fc_upld_timer
, (unsigned long)tgt
);
285 mod_timer(&tgt
->upld_timer
, jiffies
+ BNX2FC_FW_TIMEOUT
);
287 wait_event_interruptible(tgt
->upld_wait
,
289 BNX2FC_FLAG_UPLD_REQ_COMPL
,
292 if (!(test_bit(BNX2FC_FLAG_DESTROYED
, &tgt
->flags
)))
293 printk(KERN_ERR PFX
"ERROR!! destroy timed out\n");
295 BNX2FC_TGT_DBG(tgt
, "destroy wait complete flags = 0x%lx\n",
297 if (signal_pending(current
))
298 flush_signals(current
);
300 del_timer_sync(&tgt
->upld_timer
);
303 printk(KERN_ERR PFX
"ERROR!! DISABLE req timed out, destroy"
304 " not sent to FW\n");
306 /* Free session resources */
307 bnx2fc_free_session_resc(hba
, tgt
);
308 bnx2fc_free_conn_id(hba
, tgt
->fcoe_conn_id
);
311 static int bnx2fc_init_tgt(struct bnx2fc_rport
*tgt
,
312 struct fcoe_port
*port
,
313 struct fc_rport_priv
*rdata
)
316 struct fc_rport
*rport
= rdata
->rport
;
317 struct bnx2fc_hba
*hba
= port
->priv
;
323 if (hba
->num_ofld_sess
>= BNX2FC_NUM_MAX_SESS
) {
324 BNX2FC_TGT_DBG(tgt
, "exceeded max sessions. logoff this tgt\n");
325 tgt
->fcoe_conn_id
= -1;
329 tgt
->fcoe_conn_id
= bnx2fc_alloc_conn_id(hba
, tgt
);
330 if (tgt
->fcoe_conn_id
== -1)
333 BNX2FC_TGT_DBG(tgt
, "init_tgt - conn_id = 0x%x\n", tgt
->fcoe_conn_id
);
335 tgt
->max_sqes
= BNX2FC_SQ_WQES_MAX
;
336 tgt
->max_rqes
= BNX2FC_RQ_WQES_MAX
;
337 tgt
->max_cqes
= BNX2FC_CQ_WQES_MAX
;
339 /* Initialize the toggle bit */
340 tgt
->sq_curr_toggle_bit
= 1;
341 tgt
->cq_curr_toggle_bit
= 1;
342 tgt
->sq_prod_idx
= 0;
343 tgt
->cq_cons_idx
= 0;
344 tgt
->rq_prod_idx
= 0x8000;
345 tgt
->rq_cons_idx
= 0;
346 atomic_set(&tgt
->num_active_ios
, 0);
348 tgt
->work_time_slice
= 2;
350 spin_lock_init(&tgt
->tgt_lock
);
351 spin_lock_init(&tgt
->cq_lock
);
353 /* Initialize active_cmd_queue list */
354 INIT_LIST_HEAD(&tgt
->active_cmd_queue
);
356 /* Initialize IO retire queue */
357 INIT_LIST_HEAD(&tgt
->io_retire_queue
);
359 INIT_LIST_HEAD(&tgt
->els_queue
);
361 /* Initialize active_tm_queue list */
362 INIT_LIST_HEAD(&tgt
->active_tm_queue
);
364 init_waitqueue_head(&tgt
->ofld_wait
);
365 init_waitqueue_head(&tgt
->upld_wait
);
371 * This event_callback is called after successful completion of libfc
372 * initiated target login. bnx2fc can proceed with initiating the session
375 void bnx2fc_rport_event_handler(struct fc_lport
*lport
,
376 struct fc_rport_priv
*rdata
,
377 enum fc_rport_event event
)
379 struct fcoe_port
*port
= lport_priv(lport
);
380 struct bnx2fc_hba
*hba
= port
->priv
;
381 struct fc_rport
*rport
= rdata
->rport
;
382 struct fc_rport_libfc_priv
*rp
;
383 struct bnx2fc_rport
*tgt
;
386 BNX2FC_HBA_DBG(lport
, "rport_event_hdlr: event = %d, port_id = 0x%x\n",
387 event
, rdata
->ids
.port_id
);
391 printk(KERN_ALERT PFX
"rport is NULL: ERROR!\n");
396 if (rport
->port_id
== FC_FID_DIR_SERV
) {
398 * bnx2fc_rport structure doesn't exist for
400 * We should not come here, as lport will
401 * take care of fabric login
403 printk(KERN_ALERT PFX
"%x - rport_event_handler ERROR\n",
408 if (rdata
->spp_type
!= FC_TYPE_FCP
) {
409 BNX2FC_HBA_DBG(lport
, "not FCP type target."
410 " not offloading\n");
413 if (!(rdata
->ids
.roles
& FC_RPORT_ROLE_FCP_TARGET
)) {
414 BNX2FC_HBA_DBG(lport
, "not FCP_TARGET"
415 " not offloading\n");
420 * Offlaod process is protected with hba mutex.
421 * Use the same mutex_lock for upload process too
423 mutex_lock(&hba
->hba_mutex
);
424 tgt
= (struct bnx2fc_rport
*)&rp
[1];
426 /* This can happen when ADISC finds the same target */
427 if (test_bit(BNX2FC_FLAG_OFFLOADED
, &tgt
->flags
)) {
428 BNX2FC_TGT_DBG(tgt
, "already offloaded\n");
429 mutex_unlock(&hba
->hba_mutex
);
434 * Offload the session. This is a blocking call, and will
435 * wait until the session is offloaded.
437 bnx2fc_offload_session(port
, tgt
, rdata
);
439 BNX2FC_TGT_DBG(tgt
, "OFFLOAD num_ofld_sess = %d\n",
442 if (test_bit(BNX2FC_FLAG_OFFLOADED
, &tgt
->flags
)) {
444 * Session is offloaded and enabled. Map
445 * doorbell register for this target
447 BNX2FC_TGT_DBG(tgt
, "sess offloaded\n");
448 /* This counter is protected with hba mutex */
449 hba
->num_ofld_sess
++;
451 set_bit(BNX2FC_FLAG_SESSION_READY
, &tgt
->flags
);
454 * Offload or enable would have failed.
455 * In offload/enable completion path, the
456 * rport would have already been removed
458 BNX2FC_TGT_DBG(tgt
, "Port is being logged off as "
459 "offloaded flag not set\n");
461 mutex_unlock(&hba
->hba_mutex
);
464 case RPORT_EV_FAILED
:
466 port_id
= rdata
->ids
.port_id
;
467 if (port_id
== FC_FID_DIR_SERV
)
471 printk(KERN_ALERT PFX
"%x - rport not created Yet!!\n",
476 mutex_lock(&hba
->hba_mutex
);
478 * Perform session upload. Note that rdata->peers is already
479 * removed from disc->rports list before we get this event.
481 tgt
= (struct bnx2fc_rport
*)&rp
[1];
483 if (!(test_bit(BNX2FC_FLAG_OFFLOADED
, &tgt
->flags
))) {
484 mutex_unlock(&hba
->hba_mutex
);
487 clear_bit(BNX2FC_FLAG_SESSION_READY
, &tgt
->flags
);
489 bnx2fc_upload_session(port
, tgt
);
490 hba
->num_ofld_sess
--;
491 BNX2FC_TGT_DBG(tgt
, "UPLOAD num_ofld_sess = %d\n",
494 * Try to wake up the linkdown wait thread. If num_ofld_sess
495 * is 0, the waiting therad wakes up
497 if ((hba
->wait_for_link_down
) &&
498 (hba
->num_ofld_sess
== 0)) {
499 wake_up_interruptible(&hba
->shutdown_wait
);
501 if (test_bit(BNX2FC_FLAG_EXPL_LOGO
, &tgt
->flags
)) {
502 printk(KERN_ERR PFX
"Relogin to the tgt\n");
503 mutex_lock(&lport
->disc
.disc_mutex
);
504 lport
->tt
.rport_login(rdata
);
505 mutex_unlock(&lport
->disc
.disc_mutex
);
507 mutex_unlock(&hba
->hba_mutex
);
517 * bnx2fc_tgt_lookup() - Lookup a bnx2fc_rport by port_id
519 * @port: fcoe_port struct to lookup the target port on
520 * @port_id: The remote port ID to look up
522 struct bnx2fc_rport
*bnx2fc_tgt_lookup(struct fcoe_port
*port
,
525 struct bnx2fc_hba
*hba
= port
->priv
;
526 struct bnx2fc_rport
*tgt
;
527 struct fc_rport_priv
*rdata
;
530 for (i
= 0; i
< BNX2FC_NUM_MAX_SESS
; i
++) {
531 tgt
= hba
->tgt_ofld_list
[i
];
532 if ((tgt
) && (tgt
->port
== port
)) {
534 if (rdata
->ids
.port_id
== port_id
) {
535 if (rdata
->rp_state
!= RPORT_ST_DELETE
) {
536 BNX2FC_TGT_DBG(tgt
, "rport "
540 printk(KERN_ERR PFX
"rport 0x%x "
541 "is in DELETED state\n",
553 * bnx2fc_alloc_conn_id - allocates FCOE Connection id
555 * @hba: pointer to adapter structure
556 * @tgt: pointer to bnx2fc_rport structure
558 static u32
bnx2fc_alloc_conn_id(struct bnx2fc_hba
*hba
,
559 struct bnx2fc_rport
*tgt
)
563 /* called with hba mutex held */
566 * tgt_ofld_list access is synchronized using
567 * both hba mutex and hba lock. Atleast hba mutex or
568 * hba lock needs to be held for read access.
571 spin_lock_bh(&hba
->hba_lock
);
572 next
= hba
->next_conn_id
;
573 conn_id
= hba
->next_conn_id
++;
574 if (hba
->next_conn_id
== BNX2FC_NUM_MAX_SESS
)
575 hba
->next_conn_id
= 0;
577 while (hba
->tgt_ofld_list
[conn_id
] != NULL
) {
579 if (conn_id
== BNX2FC_NUM_MAX_SESS
)
582 if (conn_id
== next
) {
583 /* No free conn_ids are available */
584 spin_unlock_bh(&hba
->hba_lock
);
588 hba
->tgt_ofld_list
[conn_id
] = tgt
;
589 tgt
->fcoe_conn_id
= conn_id
;
590 spin_unlock_bh(&hba
->hba_lock
);
594 static void bnx2fc_free_conn_id(struct bnx2fc_hba
*hba
, u32 conn_id
)
596 /* called with hba mutex held */
597 spin_lock_bh(&hba
->hba_lock
);
598 hba
->tgt_ofld_list
[conn_id
] = NULL
;
599 hba
->next_conn_id
= conn_id
;
600 spin_unlock_bh(&hba
->hba_lock
);
604 *bnx2fc_alloc_session_resc - Allocate qp resources for the session
607 static int bnx2fc_alloc_session_resc(struct bnx2fc_hba
*hba
,
608 struct bnx2fc_rport
*tgt
)
614 /* Allocate and map SQ */
615 tgt
->sq_mem_size
= tgt
->max_sqes
* BNX2FC_SQ_WQE_SIZE
;
616 tgt
->sq_mem_size
= (tgt
->sq_mem_size
+ (PAGE_SIZE
- 1)) & PAGE_MASK
;
618 tgt
->sq
= dma_alloc_coherent(&hba
->pcidev
->dev
, tgt
->sq_mem_size
,
619 &tgt
->sq_dma
, GFP_KERNEL
);
621 printk(KERN_ALERT PFX
"unable to allocate SQ memory %d\n",
623 goto mem_alloc_failure
;
625 memset(tgt
->sq
, 0, tgt
->sq_mem_size
);
627 /* Allocate and map CQ */
628 tgt
->cq_mem_size
= tgt
->max_cqes
* BNX2FC_CQ_WQE_SIZE
;
629 tgt
->cq_mem_size
= (tgt
->cq_mem_size
+ (PAGE_SIZE
- 1)) & PAGE_MASK
;
631 tgt
->cq
= dma_alloc_coherent(&hba
->pcidev
->dev
, tgt
->cq_mem_size
,
632 &tgt
->cq_dma
, GFP_KERNEL
);
634 printk(KERN_ALERT PFX
"unable to allocate CQ memory %d\n",
636 goto mem_alloc_failure
;
638 memset(tgt
->cq
, 0, tgt
->cq_mem_size
);
640 /* Allocate and map RQ and RQ PBL */
641 tgt
->rq_mem_size
= tgt
->max_rqes
* BNX2FC_RQ_WQE_SIZE
;
642 tgt
->rq_mem_size
= (tgt
->rq_mem_size
+ (PAGE_SIZE
- 1)) & PAGE_MASK
;
644 tgt
->rq
= dma_alloc_coherent(&hba
->pcidev
->dev
, tgt
->rq_mem_size
,
645 &tgt
->rq_dma
, GFP_KERNEL
);
647 printk(KERN_ALERT PFX
"unable to allocate RQ memory %d\n",
649 goto mem_alloc_failure
;
651 memset(tgt
->rq
, 0, tgt
->rq_mem_size
);
653 tgt
->rq_pbl_size
= (tgt
->rq_mem_size
/ PAGE_SIZE
) * sizeof(void *);
654 tgt
->rq_pbl_size
= (tgt
->rq_pbl_size
+ (PAGE_SIZE
- 1)) & PAGE_MASK
;
656 tgt
->rq_pbl
= dma_alloc_coherent(&hba
->pcidev
->dev
, tgt
->rq_pbl_size
,
657 &tgt
->rq_pbl_dma
, GFP_KERNEL
);
659 printk(KERN_ALERT PFX
"unable to allocate RQ PBL %d\n",
661 goto mem_alloc_failure
;
664 memset(tgt
->rq_pbl
, 0, tgt
->rq_pbl_size
);
665 num_pages
= tgt
->rq_mem_size
/ PAGE_SIZE
;
667 pbl
= (u32
*)tgt
->rq_pbl
;
669 while (num_pages
--) {
672 *pbl
= (u32
)((u64
)page
>> 32);
677 /* Allocate and map XFERQ */
678 tgt
->xferq_mem_size
= tgt
->max_sqes
* BNX2FC_XFERQ_WQE_SIZE
;
679 tgt
->xferq_mem_size
= (tgt
->xferq_mem_size
+ (PAGE_SIZE
- 1)) &
682 tgt
->xferq
= dma_alloc_coherent(&hba
->pcidev
->dev
, tgt
->xferq_mem_size
,
683 &tgt
->xferq_dma
, GFP_KERNEL
);
685 printk(KERN_ALERT PFX
"unable to allocate XFERQ %d\n",
686 tgt
->xferq_mem_size
);
687 goto mem_alloc_failure
;
689 memset(tgt
->xferq
, 0, tgt
->xferq_mem_size
);
691 /* Allocate and map CONFQ & CONFQ PBL */
692 tgt
->confq_mem_size
= tgt
->max_sqes
* BNX2FC_CONFQ_WQE_SIZE
;
693 tgt
->confq_mem_size
= (tgt
->confq_mem_size
+ (PAGE_SIZE
- 1)) &
696 tgt
->confq
= dma_alloc_coherent(&hba
->pcidev
->dev
, tgt
->confq_mem_size
,
697 &tgt
->confq_dma
, GFP_KERNEL
);
699 printk(KERN_ALERT PFX
"unable to allocate CONFQ %d\n",
700 tgt
->confq_mem_size
);
701 goto mem_alloc_failure
;
703 memset(tgt
->confq
, 0, tgt
->confq_mem_size
);
705 tgt
->confq_pbl_size
=
706 (tgt
->confq_mem_size
/ PAGE_SIZE
) * sizeof(void *);
707 tgt
->confq_pbl_size
=
708 (tgt
->confq_pbl_size
+ (PAGE_SIZE
- 1)) & PAGE_MASK
;
710 tgt
->confq_pbl
= dma_alloc_coherent(&hba
->pcidev
->dev
,
712 &tgt
->confq_pbl_dma
, GFP_KERNEL
);
713 if (!tgt
->confq_pbl
) {
714 printk(KERN_ALERT PFX
"unable to allocate CONFQ PBL %d\n",
715 tgt
->confq_pbl_size
);
716 goto mem_alloc_failure
;
719 memset(tgt
->confq_pbl
, 0, tgt
->confq_pbl_size
);
720 num_pages
= tgt
->confq_mem_size
/ PAGE_SIZE
;
721 page
= tgt
->confq_dma
;
722 pbl
= (u32
*)tgt
->confq_pbl
;
724 while (num_pages
--) {
727 *pbl
= (u32
)((u64
)page
>> 32);
732 /* Allocate and map ConnDB */
733 tgt
->conn_db_mem_size
= sizeof(struct fcoe_conn_db
);
735 tgt
->conn_db
= dma_alloc_coherent(&hba
->pcidev
->dev
,
736 tgt
->conn_db_mem_size
,
737 &tgt
->conn_db_dma
, GFP_KERNEL
);
739 printk(KERN_ALERT PFX
"unable to allocate conn_db %d\n",
740 tgt
->conn_db_mem_size
);
741 goto mem_alloc_failure
;
743 memset(tgt
->conn_db
, 0, tgt
->conn_db_mem_size
);
746 /* Allocate and map LCQ */
747 tgt
->lcq_mem_size
= (tgt
->max_sqes
+ 8) * BNX2FC_SQ_WQE_SIZE
;
748 tgt
->lcq_mem_size
= (tgt
->lcq_mem_size
+ (PAGE_SIZE
- 1)) &
751 tgt
->lcq
= dma_alloc_coherent(&hba
->pcidev
->dev
, tgt
->lcq_mem_size
,
752 &tgt
->lcq_dma
, GFP_KERNEL
);
755 printk(KERN_ALERT PFX
"unable to allocate lcq %d\n",
757 goto mem_alloc_failure
;
759 memset(tgt
->lcq
, 0, tgt
->lcq_mem_size
);
762 tgt
->conn_db
->cq_arm
.lo
= -1;
763 tgt
->conn_db
->rq_prod
= 0x8000;
768 bnx2fc_free_session_resc(hba
, tgt
);
769 bnx2fc_free_conn_id(hba
, tgt
->fcoe_conn_id
);
774 * bnx2i_free_session_resc - free qp resources for the session
776 * @hba: adapter structure pointer
777 * @tgt: bnx2fc_rport structure pointer
779 * Free QP resources - SQ/RQ/CQ/XFERQ memory and PBL
781 static void bnx2fc_free_session_resc(struct bnx2fc_hba
*hba
,
782 struct bnx2fc_rport
*tgt
)
784 BNX2FC_TGT_DBG(tgt
, "Freeing up session resources\n");
787 iounmap(tgt
->ctx_base
);
788 tgt
->ctx_base
= NULL
;
792 dma_free_coherent(&hba
->pcidev
->dev
, tgt
->lcq_mem_size
,
793 tgt
->lcq
, tgt
->lcq_dma
);
798 dma_free_coherent(&hba
->pcidev
->dev
, tgt
->conn_db_mem_size
,
799 tgt
->conn_db
, tgt
->conn_db_dma
);
802 /* Free confq and confq pbl */
803 if (tgt
->confq_pbl
) {
804 dma_free_coherent(&hba
->pcidev
->dev
, tgt
->confq_pbl_size
,
805 tgt
->confq_pbl
, tgt
->confq_pbl_dma
);
806 tgt
->confq_pbl
= NULL
;
809 dma_free_coherent(&hba
->pcidev
->dev
, tgt
->confq_mem_size
,
810 tgt
->confq
, tgt
->confq_dma
);
815 dma_free_coherent(&hba
->pcidev
->dev
, tgt
->xferq_mem_size
,
816 tgt
->xferq
, tgt
->xferq_dma
);
819 /* Free RQ PBL and RQ */
821 dma_free_coherent(&hba
->pcidev
->dev
, tgt
->rq_pbl_size
,
822 tgt
->rq_pbl
, tgt
->rq_pbl_dma
);
826 dma_free_coherent(&hba
->pcidev
->dev
, tgt
->rq_mem_size
,
827 tgt
->rq
, tgt
->rq_dma
);
831 spin_lock_bh(&tgt
->cq_lock
);
833 dma_free_coherent(&hba
->pcidev
->dev
, tgt
->cq_mem_size
,
834 tgt
->cq
, tgt
->cq_dma
);
837 spin_unlock_bh(&tgt
->cq_lock
);
840 dma_free_coherent(&hba
->pcidev
->dev
, tgt
->sq_mem_size
,
841 tgt
->sq
, tgt
->sq_dma
);