@@ -763,50 +763,86 @@ static void fdls_send_fabric_abts(struct fnic_iport_s *iport)
763763 iport -> fabric .timer_pending = 1 ;
764764}
765765
766- static void fdls_send_fdmi_abts (struct fnic_iport_s * iport )
766+ static uint8_t * fdls_alloc_init_fdmi_abts_frame (struct fnic_iport_s * iport ,
767+ uint16_t oxid )
767768{
768- uint8_t * frame ;
769+ struct fc_frame_header * pfdmi_abts ;
769770 uint8_t d_id [3 ];
771+ uint8_t * frame ;
770772 struct fnic * fnic = iport -> fnic ;
771- struct fc_frame_header * pfabric_abts ;
772- unsigned long fdmi_tov ;
773- uint16_t oxid ;
774- uint16_t frame_size = FNIC_ETH_FCOE_HDRS_OFFSET +
775- sizeof (struct fc_frame_header );
776773
777774 frame = fdls_alloc_frame (iport );
778775 if (frame == NULL ) {
779776 FNIC_FCS_DBG (KERN_ERR , fnic -> host , fnic -> fnic_num ,
780777 "Failed to allocate frame to send FDMI ABTS" );
781- return ;
778+ return NULL ;
782779 }
783780
784- pfabric_abts = (struct fc_frame_header * ) (frame + FNIC_ETH_FCOE_HDRS_OFFSET );
781+ pfdmi_abts = (struct fc_frame_header * ) (frame + FNIC_ETH_FCOE_HDRS_OFFSET );
785782 fdls_init_fabric_abts_frame (frame , iport );
786783
787784 hton24 (d_id , FC_FID_MGMT_SERV );
788- FNIC_STD_SET_D_ID (* pfabric_abts , d_id );
785+ FNIC_STD_SET_D_ID (* pfdmi_abts , d_id );
786+ FNIC_STD_SET_OX_ID (* pfdmi_abts , oxid );
787+
788+ return frame ;
789+ }
790+
791+ static void fdls_send_fdmi_abts (struct fnic_iport_s * iport )
792+ {
793+ uint8_t * frame ;
794+ struct fnic * fnic = iport -> fnic ;
795+ unsigned long fdmi_tov ;
796+ uint16_t frame_size = FNIC_ETH_FCOE_HDRS_OFFSET +
797+ sizeof (struct fc_frame_header );
789798
790799 if (iport -> fabric .fdmi_pending & FDLS_FDMI_PLOGI_PENDING ) {
791- oxid = iport -> active_oxid_fdmi_plogi ;
792- FNIC_STD_SET_OX_ID (* pfabric_abts , oxid );
800+ frame = fdls_alloc_init_fdmi_abts_frame (iport ,
801+ iport -> active_oxid_fdmi_plogi );
802+ if (frame == NULL )
803+ return ;
804+
805+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
806+ "0x%x: FDLS send FDMI PLOGI abts. iport->fabric.state: %d oxid: 0x%x" ,
807+ iport -> fcid , iport -> fabric .state , iport -> active_oxid_fdmi_plogi );
793808 fnic_send_fcoe_frame (iport , frame , frame_size );
794809 } else {
795810 if (iport -> fabric .fdmi_pending & FDLS_FDMI_REG_HBA_PENDING ) {
796- oxid = iport -> active_oxid_fdmi_rhba ;
797- FNIC_STD_SET_OX_ID (* pfabric_abts , oxid );
811+ frame = fdls_alloc_init_fdmi_abts_frame (iport ,
812+ iport -> active_oxid_fdmi_rhba );
813+ if (frame == NULL )
814+ return ;
815+
816+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
817+ "0x%x: FDLS send FDMI RHBA abts. iport->fabric.state: %d oxid: 0x%x" ,
818+ iport -> fcid , iport -> fabric .state , iport -> active_oxid_fdmi_rhba );
798819 fnic_send_fcoe_frame (iport , frame , frame_size );
799820 }
800821 if (iport -> fabric .fdmi_pending & FDLS_FDMI_RPA_PENDING ) {
801- oxid = iport -> active_oxid_fdmi_rpa ;
802- FNIC_STD_SET_OX_ID (* pfabric_abts , oxid );
822+ frame = fdls_alloc_init_fdmi_abts_frame (iport ,
823+ iport -> active_oxid_fdmi_rpa );
824+ if (frame == NULL ) {
825+ if (iport -> fabric .fdmi_pending & FDLS_FDMI_REG_HBA_PENDING )
826+ goto arm_timer ;
827+ else
828+ return ;
829+ }
830+
831+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
832+ "0x%x: FDLS send FDMI RPA abts. iport->fabric.state: %d oxid: 0x%x" ,
833+ iport -> fcid , iport -> fabric .state , iport -> active_oxid_fdmi_rpa );
803834 fnic_send_fcoe_frame (iport , frame , frame_size );
804835 }
805836 }
806837
838+ arm_timer :
807839 fdmi_tov = jiffies + msecs_to_jiffies (2 * iport -> e_d_tov );
808840 mod_timer (& iport -> fabric .fdmi_timer , round_jiffies (fdmi_tov ));
809841 iport -> fabric .fdmi_pending |= FDLS_FDMI_ABORT_PENDING ;
842+
843+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
844+ "0x%x: iport->fabric.fdmi_pending: 0x%x" ,
845+ iport -> fcid , iport -> fabric .fdmi_pending );
810846}
811847
812848static void fdls_send_fabric_flogi (struct fnic_iport_s * iport )
@@ -2244,6 +2280,21 @@ void fdls_fabric_timer_callback(struct timer_list *t)
22442280 spin_unlock_irqrestore (& fnic -> fnic_lock , flags );
22452281}
22462282
2283+ void fdls_fdmi_retry_plogi (struct fnic_iport_s * iport )
2284+ {
2285+ struct fnic * fnic = iport -> fnic ;
2286+
2287+ iport -> fabric .fdmi_pending = 0 ;
2288+ /* If max retries not exhausted, start over from fdmi plogi */
2289+ if (iport -> fabric .fdmi_retry < FDLS_FDMI_MAX_RETRY ) {
2290+ iport -> fabric .fdmi_retry ++ ;
2291+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2292+ "Retry FDMI PLOGI. FDMI retry: %d" ,
2293+ iport -> fabric .fdmi_retry );
2294+ fdls_send_fdmi_plogi (iport );
2295+ }
2296+ }
2297+
22472298void fdls_fdmi_timer_callback (struct timer_list * t )
22482299{
22492300 struct fnic_fdls_fabric_s * fabric = from_timer (fabric , t , fdmi_timer );
@@ -2255,15 +2306,15 @@ void fdls_fdmi_timer_callback(struct timer_list *t)
22552306 spin_lock_irqsave (& fnic -> fnic_lock , flags );
22562307
22572308 FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2258- "fdmi timer callback : 0x%x\n" , iport -> fabric .fdmi_pending );
2309+ "iport->fabric.fdmi_pending : 0x%x\n" , iport -> fabric .fdmi_pending );
22592310
22602311 if (!iport -> fabric .fdmi_pending ) {
22612312 /* timer expired after fdmi responses received. */
22622313 spin_unlock_irqrestore (& fnic -> fnic_lock , flags );
22632314 return ;
22642315 }
22652316 FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2266- "fdmi timer callback : 0x%x\n" , iport -> fabric .fdmi_pending );
2317+ "iport->fabric.fdmi_pending : 0x%x\n" , iport -> fabric .fdmi_pending );
22672318
22682319 /* if not abort pending, send an abort */
22692320 if (!(iport -> fabric .fdmi_pending & FDLS_FDMI_ABORT_PENDING )) {
@@ -2272,33 +2323,37 @@ void fdls_fdmi_timer_callback(struct timer_list *t)
22722323 return ;
22732324 }
22742325 FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2275- "fdmi timer callback : 0x%x\n" , iport -> fabric .fdmi_pending );
2326+ "iport->fabric.fdmi_pending : 0x%x\n" , iport -> fabric .fdmi_pending );
22762327
22772328 /* ABTS pending for an active fdmi request that is pending.
22782329 * That means FDMI ABTS timed out
22792330 * Schedule to free the OXID after 2*r_a_tov and proceed
22802331 */
22812332 if (iport -> fabric .fdmi_pending & FDLS_FDMI_PLOGI_PENDING ) {
2333+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2334+ "FDMI PLOGI ABTS timed out. Schedule oxid free: 0x%x\n" ,
2335+ iport -> active_oxid_fdmi_plogi );
22822336 fdls_schedule_oxid_free (iport , & iport -> active_oxid_fdmi_plogi );
22832337 } else {
2284- if (iport -> fabric .fdmi_pending & FDLS_FDMI_REG_HBA_PENDING )
2338+ if (iport -> fabric .fdmi_pending & FDLS_FDMI_REG_HBA_PENDING ) {
2339+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2340+ "FDMI RHBA ABTS timed out. Schedule oxid free: 0x%x\n" ,
2341+ iport -> active_oxid_fdmi_rhba );
22852342 fdls_schedule_oxid_free (iport , & iport -> active_oxid_fdmi_rhba );
2286- if (iport -> fabric .fdmi_pending & FDLS_FDMI_RPA_PENDING )
2343+ }
2344+ if (iport -> fabric .fdmi_pending & FDLS_FDMI_RPA_PENDING ) {
2345+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2346+ "FDMI RPA ABTS timed out. Schedule oxid free: 0x%x\n" ,
2347+ iport -> active_oxid_fdmi_rpa );
22872348 fdls_schedule_oxid_free (iport , & iport -> active_oxid_fdmi_rpa );
2349+ }
22882350 }
22892351 FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2290- "fdmi timer callback : 0x%x\n" , iport -> fabric .fdmi_pending );
2352+ "iport->fabric.fdmi_pending : 0x%x\n" , iport -> fabric .fdmi_pending );
22912353
2292- iport -> fabric .fdmi_pending = 0 ;
2293- /* If max retries not exhaused, start over from fdmi plogi */
2294- if (iport -> fabric .fdmi_retry < FDLS_FDMI_MAX_RETRY ) {
2295- iport -> fabric .fdmi_retry ++ ;
2296- FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2297- "retry fdmi timer %d" , iport -> fabric .fdmi_retry );
2298- fdls_send_fdmi_plogi (iport );
2299- }
2354+ fdls_fdmi_retry_plogi (iport );
23002355 FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2301- "fdmi timer callback : 0x%x\n" , iport -> fabric .fdmi_pending );
2356+ "iport->fabric.fdmi_pending : 0x%x\n" , iport -> fabric .fdmi_pending );
23022357 spin_unlock_irqrestore (& fnic -> fnic_lock , flags );
23032358}
23042359
@@ -3713,13 +3768,60 @@ static void fdls_process_fdmi_abts_rsp(struct fnic_iport_s *iport,
37133768
37143769 switch (FNIC_FRAME_TYPE (oxid )) {
37153770 case FNIC_FRAME_TYPE_FDMI_PLOGI :
3771+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
3772+ "Received FDMI PLOGI ABTS rsp with oxid: 0x%x" , oxid );
3773+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
3774+ "0x%x: iport->fabric.fdmi_pending: 0x%x" ,
3775+ iport -> fcid , iport -> fabric .fdmi_pending );
37163776 fdls_free_oxid (iport , oxid , & iport -> active_oxid_fdmi_plogi );
3777+
3778+ iport -> fabric .fdmi_pending &= ~FDLS_FDMI_PLOGI_PENDING ;
3779+ iport -> fabric .fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING ;
3780+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
3781+ "0x%x: iport->fabric.fdmi_pending: 0x%x" ,
3782+ iport -> fcid , iport -> fabric .fdmi_pending );
37173783 break ;
37183784 case FNIC_FRAME_TYPE_FDMI_RHBA :
3785+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
3786+ "Received FDMI RHBA ABTS rsp with oxid: 0x%x" , oxid );
3787+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
3788+ "0x%x: iport->fabric.fdmi_pending: 0x%x" ,
3789+ iport -> fcid , iport -> fabric .fdmi_pending );
3790+
3791+ iport -> fabric .fdmi_pending &= ~FDLS_FDMI_REG_HBA_PENDING ;
3792+
3793+ /* If RPA is still pending, don't turn off ABORT PENDING.
3794+ * We count on the timer to detect the ABTS timeout and take
3795+ * corrective action.
3796+ */
3797+ if (!(iport -> fabric .fdmi_pending & FDLS_FDMI_RPA_PENDING ))
3798+ iport -> fabric .fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING ;
3799+
37193800 fdls_free_oxid (iport , oxid , & iport -> active_oxid_fdmi_rhba );
3801+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
3802+ "0x%x: iport->fabric.fdmi_pending: 0x%x" ,
3803+ iport -> fcid , iport -> fabric .fdmi_pending );
37203804 break ;
37213805 case FNIC_FRAME_TYPE_FDMI_RPA :
3806+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
3807+ "Received FDMI RPA ABTS rsp with oxid: 0x%x" , oxid );
3808+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
3809+ "0x%x: iport->fabric.fdmi_pending: 0x%x" ,
3810+ iport -> fcid , iport -> fabric .fdmi_pending );
3811+
3812+ iport -> fabric .fdmi_pending &= ~FDLS_FDMI_RPA_PENDING ;
3813+
3814+ /* If RHBA is still pending, don't turn off ABORT PENDING.
3815+ * We count on the timer to detect the ABTS timeout and take
3816+ * corrective action.
3817+ */
3818+ if (!(iport -> fabric .fdmi_pending & FDLS_FDMI_REG_HBA_PENDING ))
3819+ iport -> fabric .fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING ;
3820+
37223821 fdls_free_oxid (iport , oxid , & iport -> active_oxid_fdmi_rpa );
3822+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
3823+ "0x%x: iport->fabric.fdmi_pending: 0x%x" ,
3824+ iport -> fcid , iport -> fabric .fdmi_pending );
37233825 break ;
37243826 default :
37253827 FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
@@ -3728,10 +3830,16 @@ static void fdls_process_fdmi_abts_rsp(struct fnic_iport_s *iport,
37283830 break ;
37293831 }
37303832
3731- del_timer_sync (& iport -> fabric .fdmi_timer );
3732- iport -> fabric .fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING ;
3733-
3734- fdls_send_fdmi_plogi (iport );
3833+ /*
3834+ * Only if ABORT PENDING is off, delete the timer, and if no other
3835+ * operations are pending, retry FDMI.
3836+ * Otherwise, let the timer pop and take the appropriate action.
3837+ */
3838+ if (!(iport -> fabric .fdmi_pending & FDLS_FDMI_ABORT_PENDING )) {
3839+ timer_delete_sync (& iport -> fabric .fdmi_timer );
3840+ if (!iport -> fabric .fdmi_pending )
3841+ fdls_fdmi_retry_plogi (iport );
3842+ }
37353843}
37363844
37373845static void
@@ -4970,9 +5078,12 @@ void fnic_fdls_link_down(struct fnic_iport_s *iport)
49705078 fdls_delete_tport (iport , tport );
49715079 }
49725080
4973- if ((fnic_fdmi_support == 1 ) && (iport -> fabric .fdmi_pending > 0 )) {
4974- del_timer_sync (& iport -> fabric .fdmi_timer );
4975- iport -> fabric .fdmi_pending = 0 ;
5081+ if (fnic_fdmi_support == 1 ) {
5082+ if (iport -> fabric .fdmi_pending > 0 ) {
5083+ timer_delete_sync (& iport -> fabric .fdmi_timer );
5084+ iport -> fabric .fdmi_pending = 0 ;
5085+ }
5086+ iport -> flags &= ~FNIC_FDMI_ACTIVE ;
49765087 }
49775088
49785089 FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
0 commit comments