aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fnic/fnic_scsi.c
diff options
context:
space:
mode:
authorJoe Eykholt <jeykholt@cisco.com>2009-11-03 14:49:22 -0500
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:01:19 -0500
commit78112e5558064cb4d2e355aed87b2036fcdfe3dd (patch)
treedf34a54d3dcfb503621e3cdd64b22dc173a6722e /drivers/scsi/fnic/fnic_scsi.c
parent386309ce927a308d7742a6fb24a536d3383fbd49 (diff)
[SCSI] fnic: Add FIP support to the fnic driver
Use libfcoe as a common FIP implementation with fcoe. FIP or non-FIP mode is fully automatic if the firmware supports and enables it. Even if FIP is not supported, this uses libfcoe for the non-FIP handling of FLOGI and its response. Use the new lport_set_port_id() notification to capture successful FLOGI responses and port_id resets. While transitioning between Ethernet and FC mode, all rx and tx FC frames are queued. In Ethernet mode, all frames are passed to the exchange manager to capture FLOGI responses. Change to set data_src_addr to the ctl_src_addr whenever it would have previously been zero because we're not logged in. This seems safer so we'll never send a frame with a 0 source MAC. This also eliminates a special case for sending FLOGI frames. Signed-off-by: Joe Eykholt <jeykholt@cisco.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/fnic/fnic_scsi.c')
-rw-r--r--drivers/scsi/fnic/fnic_scsi.c73
1 files changed, 34 insertions, 39 deletions
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
index 8d26d7a9f01b..65a39b0f6dc2 100644
--- a/drivers/scsi/fnic/fnic_scsi.c
+++ b/drivers/scsi/fnic/fnic_scsi.c
@@ -174,6 +174,9 @@ int fnic_fw_reset_handler(struct fnic *fnic)
174 int ret = 0; 174 int ret = 0;
175 unsigned long flags; 175 unsigned long flags;
176 176
177 skb_queue_purge(&fnic->frame_queue);
178 skb_queue_purge(&fnic->tx_queue);
179
177 spin_lock_irqsave(&fnic->wq_copy_lock[0], flags); 180 spin_lock_irqsave(&fnic->wq_copy_lock[0], flags);
178 181
179 if (vnic_wq_copy_desc_avail(wq) <= fnic->wq_copy_desc_low[0]) 182 if (vnic_wq_copy_desc_avail(wq) <= fnic->wq_copy_desc_low[0])
@@ -200,9 +203,11 @@ int fnic_fw_reset_handler(struct fnic *fnic)
200 * fnic_flogi_reg_handler 203 * fnic_flogi_reg_handler
201 * Routine to send flogi register msg to fw 204 * Routine to send flogi register msg to fw
202 */ 205 */
203int fnic_flogi_reg_handler(struct fnic *fnic) 206int fnic_flogi_reg_handler(struct fnic *fnic, u32 fc_id)
204{ 207{
205 struct vnic_wq_copy *wq = &fnic->wq_copy[0]; 208 struct vnic_wq_copy *wq = &fnic->wq_copy[0];
209 enum fcpio_flogi_reg_format_type format;
210 struct fc_lport *lp = fnic->lport;
206 u8 gw_mac[ETH_ALEN]; 211 u8 gw_mac[ETH_ALEN];
207 int ret = 0; 212 int ret = 0;
208 unsigned long flags; 213 unsigned long flags;
@@ -217,23 +222,32 @@ int fnic_flogi_reg_handler(struct fnic *fnic)
217 goto flogi_reg_ioreq_end; 222 goto flogi_reg_ioreq_end;
218 } 223 }
219 224
220 if (fnic->fcoui_mode) 225 if (fnic->ctlr.map_dest) {
221 memset(gw_mac, 0xff, ETH_ALEN); 226 memset(gw_mac, 0xff, ETH_ALEN);
222 else 227 format = FCPIO_FLOGI_REG_DEF_DEST;
223 memcpy(gw_mac, fnic->dest_addr, ETH_ALEN); 228 } else {
229 memcpy(gw_mac, fnic->ctlr.dest_addr, ETH_ALEN);
230 format = FCPIO_FLOGI_REG_GW_DEST;
231 }
224 232
225 fnic_queue_wq_copy_desc_flogi_reg(wq, SCSI_NO_TAG, 233 if ((fnic->config.flags & VFCF_FIP_CAPABLE) && !fnic->ctlr.map_dest) {
226 FCPIO_FLOGI_REG_GW_DEST, 234 fnic_queue_wq_copy_desc_fip_reg(wq, SCSI_NO_TAG,
227 fnic->s_id, 235 fc_id, gw_mac,
228 gw_mac); 236 fnic->data_src_addr,
237 lp->r_a_tov, lp->e_d_tov);
238 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
239 "FLOGI FIP reg issued fcid %x src %pM dest %pM\n",
240 fc_id, fnic->data_src_addr, gw_mac);
241 } else {
242 fnic_queue_wq_copy_desc_flogi_reg(wq, SCSI_NO_TAG,
243 format, fc_id, gw_mac);
244 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
245 "FLOGI reg issued fcid %x map %d dest %pM\n",
246 fc_id, fnic->ctlr.map_dest, gw_mac);
247 }
229 248
230flogi_reg_ioreq_end: 249flogi_reg_ioreq_end:
231 spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags); 250 spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags);
232
233 if (!ret)
234 FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
235 "flog reg issued\n");
236
237 return ret; 251 return ret;
238} 252}
239 253
@@ -453,7 +467,6 @@ static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic,
453 u8 hdr_status; 467 u8 hdr_status;
454 struct fcpio_tag tag; 468 struct fcpio_tag tag;
455 int ret = 0; 469 int ret = 0;
456 struct fc_frame *flogi;
457 unsigned long flags; 470 unsigned long flags;
458 471
459 fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag); 472 fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag);
@@ -463,9 +476,6 @@ static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic,
463 476
464 spin_lock_irqsave(&fnic->fnic_lock, flags); 477 spin_lock_irqsave(&fnic->fnic_lock, flags);
465 478
466 flogi = fnic->flogi;
467 fnic->flogi = NULL;
468
469 /* fnic should be in FC_TRANS_ETH_MODE */ 479 /* fnic should be in FC_TRANS_ETH_MODE */
470 if (fnic->state == FNIC_IN_FC_TRANS_ETH_MODE) { 480 if (fnic->state == FNIC_IN_FC_TRANS_ETH_MODE) {
471 /* Check status of reset completion */ 481 /* Check status of reset completion */
@@ -506,17 +516,14 @@ static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic,
506 * free the flogi frame. Else, send it out 516 * free the flogi frame. Else, send it out
507 */ 517 */
508 if (fnic->remove_wait || ret) { 518 if (fnic->remove_wait || ret) {
509 fnic->flogi_oxid = FC_XID_UNKNOWN;
510 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 519 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
511 if (flogi) 520 skb_queue_purge(&fnic->tx_queue);
512 dev_kfree_skb_irq(fp_skb(flogi));
513 goto reset_cmpl_handler_end; 521 goto reset_cmpl_handler_end;
514 } 522 }
515 523
516 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 524 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
517 525
518 if (flogi) 526 fnic_flush_tx(fnic);
519 ret = fnic_send_frame(fnic, flogi);
520 527
521 reset_cmpl_handler_end: 528 reset_cmpl_handler_end:
522 return ret; 529 return ret;
@@ -533,18 +540,13 @@ static int fnic_fcpio_flogi_reg_cmpl_handler(struct fnic *fnic,
533 u8 hdr_status; 540 u8 hdr_status;
534 struct fcpio_tag tag; 541 struct fcpio_tag tag;
535 int ret = 0; 542 int ret = 0;
536 struct fc_frame *flogi_resp = NULL;
537 unsigned long flags; 543 unsigned long flags;
538 struct sk_buff *skb;
539 544
540 fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag); 545 fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag);
541 546
542 /* Update fnic state based on status of flogi reg completion */ 547 /* Update fnic state based on status of flogi reg completion */
543 spin_lock_irqsave(&fnic->fnic_lock, flags); 548 spin_lock_irqsave(&fnic->fnic_lock, flags);
544 549
545 flogi_resp = fnic->flogi_resp;
546 fnic->flogi_resp = NULL;
547
548 if (fnic->state == FNIC_IN_ETH_TRANS_FC_MODE) { 550 if (fnic->state == FNIC_IN_ETH_TRANS_FC_MODE) {
549 551
550 /* Check flogi registration completion status */ 552 /* Check flogi registration completion status */
@@ -568,25 +570,17 @@ static int fnic_fcpio_flogi_reg_cmpl_handler(struct fnic *fnic,
568 ret = -1; 570 ret = -1;
569 } 571 }
570 572
571 /* Successful flogi reg cmpl, pass frame to LibFC */ 573 if (!ret) {
572 if (!ret && flogi_resp) {
573 if (fnic->stop_rx_link_events) { 574 if (fnic->stop_rx_link_events) {
574 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 575 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
575 goto reg_cmpl_handler_end; 576 goto reg_cmpl_handler_end;
576 } 577 }
577 skb = (struct sk_buff *)flogi_resp;
578 /* Use fr_flags to indicate whether flogi resp or not */
579 fr_flags(flogi_resp) = 1;
580 fr_dev(flogi_resp) = fnic->lport;
581 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 578 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
582 579
583 skb_queue_tail(&fnic->frame_queue, skb); 580 fnic_flush_tx(fnic);
584 queue_work(fnic_event_queue, &fnic->frame_work); 581 queue_work(fnic_event_queue, &fnic->frame_work);
585
586 } else { 582 } else {
587 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 583 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
588 if (flogi_resp)
589 dev_kfree_skb_irq(fp_skb(flogi_resp));
590 } 584 }
591 585
592reg_cmpl_handler_end: 586reg_cmpl_handler_end:
@@ -908,6 +902,7 @@ static int fnic_fcpio_cmpl_handler(struct vnic_dev *vdev,
908 break; 902 break;
909 903
910 case FCPIO_FLOGI_REG_CMPL: /* fw completed flogi_reg */ 904 case FCPIO_FLOGI_REG_CMPL: /* fw completed flogi_reg */
905 case FCPIO_FLOGI_FIP_REG_CMPL: /* fw completed flogi_fip_reg */
911 ret = fnic_fcpio_flogi_reg_cmpl_handler(fnic, desc); 906 ret = fnic_fcpio_flogi_reg_cmpl_handler(fnic, desc);
912 break; 907 break;
913 908
@@ -1747,7 +1742,7 @@ void fnic_scsi_abort_io(struct fc_lport *lp)
1747 fnic->remove_wait = &remove_wait; 1742 fnic->remove_wait = &remove_wait;
1748 old_state = fnic->state; 1743 old_state = fnic->state;
1749 fnic->state = FNIC_IN_FC_TRANS_ETH_MODE; 1744 fnic->state = FNIC_IN_FC_TRANS_ETH_MODE;
1750 vnic_dev_del_addr(fnic->vdev, fnic->data_src_addr); 1745 fnic_update_mac_locked(fnic, fnic->ctlr.ctl_src_addr);
1751 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 1746 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
1752 1747
1753 err = fnic_fw_reset_handler(fnic); 1748 err = fnic_fw_reset_handler(fnic);
@@ -1787,7 +1782,7 @@ void fnic_scsi_cleanup(struct fc_lport *lp)
1787 spin_lock_irqsave(&fnic->fnic_lock, flags); 1782 spin_lock_irqsave(&fnic->fnic_lock, flags);
1788 old_state = fnic->state; 1783 old_state = fnic->state;
1789 fnic->state = FNIC_IN_FC_TRANS_ETH_MODE; 1784 fnic->state = FNIC_IN_FC_TRANS_ETH_MODE;
1790 vnic_dev_del_addr(fnic->vdev, fnic->data_src_addr); 1785 fnic_update_mac_locked(fnic, fnic->ctlr.ctl_src_addr);
1791 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 1786 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
1792 1787
1793 if (fnic_fw_reset_handler(fnic)) { 1788 if (fnic_fw_reset_handler(fnic)) {