@@ -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 )
@@ -2245,6 +2281,21 @@ void fdls_fabric_timer_callback(struct timer_list *t)
22452281 spin_unlock_irqrestore (& fnic -> fnic_lock , flags );
22462282}
22472283
2284+ void fdls_fdmi_retry_plogi (struct fnic_iport_s * iport )
2285+ {
2286+ struct fnic * fnic = iport -> fnic ;
2287+
2288+ iport -> fabric .fdmi_pending = 0 ;
2289+ /* If max retries not exhausted, start over from fdmi plogi */
2290+ if (iport -> fabric .fdmi_retry < FDLS_FDMI_MAX_RETRY ) {
2291+ iport -> fabric .fdmi_retry ++ ;
2292+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2293+ "Retry FDMI PLOGI. FDMI retry: %d" ,
2294+ iport -> fabric .fdmi_retry );
2295+ fdls_send_fdmi_plogi (iport );
2296+ }
2297+ }
2298+
22482299void fdls_fdmi_timer_callback (struct timer_list * t )
22492300{
22502301 struct fnic_fdls_fabric_s * fabric = timer_container_of (fabric , t ,
@@ -2257,15 +2308,15 @@ void fdls_fdmi_timer_callback(struct timer_list *t)
22572308 spin_lock_irqsave (& fnic -> fnic_lock , flags );
22582309
22592310 FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2260- "fdmi timer callback : 0x%x\n" , iport -> fabric .fdmi_pending );
2311+ "iport->fabric.fdmi_pending : 0x%x\n" , iport -> fabric .fdmi_pending );
22612312
22622313 if (!iport -> fabric .fdmi_pending ) {
22632314 /* timer expired after fdmi responses received. */
22642315 spin_unlock_irqrestore (& fnic -> fnic_lock , flags );
22652316 return ;
22662317 }
22672318 FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2268- "fdmi timer callback : 0x%x\n" , iport -> fabric .fdmi_pending );
2319+ "iport->fabric.fdmi_pending : 0x%x\n" , iport -> fabric .fdmi_pending );
22692320
22702321 /* if not abort pending, send an abort */
22712322 if (!(iport -> fabric .fdmi_pending & FDLS_FDMI_ABORT_PENDING )) {
@@ -2274,33 +2325,37 @@ void fdls_fdmi_timer_callback(struct timer_list *t)
22742325 return ;
22752326 }
22762327 FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2277- "fdmi timer callback : 0x%x\n" , iport -> fabric .fdmi_pending );
2328+ "iport->fabric.fdmi_pending : 0x%x\n" , iport -> fabric .fdmi_pending );
22782329
22792330 /* ABTS pending for an active fdmi request that is pending.
22802331 * That means FDMI ABTS timed out
22812332 * Schedule to free the OXID after 2*r_a_tov and proceed
22822333 */
22832334 if (iport -> fabric .fdmi_pending & FDLS_FDMI_PLOGI_PENDING ) {
2335+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2336+ "FDMI PLOGI ABTS timed out. Schedule oxid free: 0x%x\n" ,
2337+ iport -> active_oxid_fdmi_plogi );
22842338 fdls_schedule_oxid_free (iport , & iport -> active_oxid_fdmi_plogi );
22852339 } else {
2286- if (iport -> fabric .fdmi_pending & FDLS_FDMI_REG_HBA_PENDING )
2340+ if (iport -> fabric .fdmi_pending & FDLS_FDMI_REG_HBA_PENDING ) {
2341+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2342+ "FDMI RHBA ABTS timed out. Schedule oxid free: 0x%x\n" ,
2343+ iport -> active_oxid_fdmi_rhba );
22872344 fdls_schedule_oxid_free (iport , & iport -> active_oxid_fdmi_rhba );
2288- if (iport -> fabric .fdmi_pending & FDLS_FDMI_RPA_PENDING )
2345+ }
2346+ if (iport -> fabric .fdmi_pending & FDLS_FDMI_RPA_PENDING ) {
2347+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2348+ "FDMI RPA ABTS timed out. Schedule oxid free: 0x%x\n" ,
2349+ iport -> active_oxid_fdmi_rpa );
22892350 fdls_schedule_oxid_free (iport , & iport -> active_oxid_fdmi_rpa );
2351+ }
22902352 }
22912353 FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2292- "fdmi timer callback : 0x%x\n" , iport -> fabric .fdmi_pending );
2354+ "iport->fabric.fdmi_pending : 0x%x\n" , iport -> fabric .fdmi_pending );
22932355
2294- iport -> fabric .fdmi_pending = 0 ;
2295- /* If max retries not exhaused, start over from fdmi plogi */
2296- if (iport -> fabric .fdmi_retry < FDLS_FDMI_MAX_RETRY ) {
2297- iport -> fabric .fdmi_retry ++ ;
2298- FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2299- "retry fdmi timer %d" , iport -> fabric .fdmi_retry );
2300- fdls_send_fdmi_plogi (iport );
2301- }
2356+ fdls_fdmi_retry_plogi (iport );
23022357 FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2303- "fdmi timer callback : 0x%x\n" , iport -> fabric .fdmi_pending );
2358+ "iport->fabric.fdmi_pending : 0x%x\n" , iport -> fabric .fdmi_pending );
23042359 spin_unlock_irqrestore (& fnic -> fnic_lock , flags );
23052360}
23062361
@@ -3715,13 +3770,60 @@ static void fdls_process_fdmi_abts_rsp(struct fnic_iport_s *iport,
37153770
37163771 switch (FNIC_FRAME_TYPE (oxid )) {
37173772 case FNIC_FRAME_TYPE_FDMI_PLOGI :
3773+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
3774+ "Received FDMI PLOGI ABTS rsp with oxid: 0x%x" , oxid );
3775+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
3776+ "0x%x: iport->fabric.fdmi_pending: 0x%x" ,
3777+ iport -> fcid , iport -> fabric .fdmi_pending );
37183778 fdls_free_oxid (iport , oxid , & iport -> active_oxid_fdmi_plogi );
3779+
3780+ iport -> fabric .fdmi_pending &= ~FDLS_FDMI_PLOGI_PENDING ;
3781+ iport -> fabric .fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING ;
3782+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
3783+ "0x%x: iport->fabric.fdmi_pending: 0x%x" ,
3784+ iport -> fcid , iport -> fabric .fdmi_pending );
37193785 break ;
37203786 case FNIC_FRAME_TYPE_FDMI_RHBA :
3787+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
3788+ "Received FDMI RHBA ABTS rsp with oxid: 0x%x" , oxid );
3789+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
3790+ "0x%x: iport->fabric.fdmi_pending: 0x%x" ,
3791+ iport -> fcid , iport -> fabric .fdmi_pending );
3792+
3793+ iport -> fabric .fdmi_pending &= ~FDLS_FDMI_REG_HBA_PENDING ;
3794+
3795+ /* If RPA is still pending, don't turn off ABORT PENDING.
3796+ * We count on the timer to detect the ABTS timeout and take
3797+ * corrective action.
3798+ */
3799+ if (!(iport -> fabric .fdmi_pending & FDLS_FDMI_RPA_PENDING ))
3800+ iport -> fabric .fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING ;
3801+
37213802 fdls_free_oxid (iport , oxid , & iport -> active_oxid_fdmi_rhba );
3803+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
3804+ "0x%x: iport->fabric.fdmi_pending: 0x%x" ,
3805+ iport -> fcid , iport -> fabric .fdmi_pending );
37223806 break ;
37233807 case FNIC_FRAME_TYPE_FDMI_RPA :
3808+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
3809+ "Received FDMI RPA ABTS rsp with oxid: 0x%x" , oxid );
3810+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
3811+ "0x%x: iport->fabric.fdmi_pending: 0x%x" ,
3812+ iport -> fcid , iport -> fabric .fdmi_pending );
3813+
3814+ iport -> fabric .fdmi_pending &= ~FDLS_FDMI_RPA_PENDING ;
3815+
3816+ /* If RHBA is still pending, don't turn off ABORT PENDING.
3817+ * We count on the timer to detect the ABTS timeout and take
3818+ * corrective action.
3819+ */
3820+ if (!(iport -> fabric .fdmi_pending & FDLS_FDMI_REG_HBA_PENDING ))
3821+ iport -> fabric .fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING ;
3822+
37243823 fdls_free_oxid (iport , oxid , & iport -> active_oxid_fdmi_rpa );
3824+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
3825+ "0x%x: iport->fabric.fdmi_pending: 0x%x" ,
3826+ iport -> fcid , iport -> fabric .fdmi_pending );
37253827 break ;
37263828 default :
37273829 FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
@@ -3730,10 +3832,16 @@ static void fdls_process_fdmi_abts_rsp(struct fnic_iport_s *iport,
37303832 break ;
37313833 }
37323834
3733- timer_delete_sync (& iport -> fabric .fdmi_timer );
3734- iport -> fabric .fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING ;
3735-
3736- fdls_send_fdmi_plogi (iport );
3835+ /*
3836+ * Only if ABORT PENDING is off, delete the timer, and if no other
3837+ * operations are pending, retry FDMI.
3838+ * Otherwise, let the timer pop and take the appropriate action.
3839+ */
3840+ if (!(iport -> fabric .fdmi_pending & FDLS_FDMI_ABORT_PENDING )) {
3841+ timer_delete_sync (& iport -> fabric .fdmi_timer );
3842+ if (!iport -> fabric .fdmi_pending )
3843+ fdls_fdmi_retry_plogi (iport );
3844+ }
37373845}
37383846
37393847static void
@@ -4972,9 +5080,12 @@ void fnic_fdls_link_down(struct fnic_iport_s *iport)
49725080 fdls_delete_tport (iport , tport );
49735081 }
49745082
4975- if ((fnic_fdmi_support == 1 ) && (iport -> fabric .fdmi_pending > 0 )) {
4976- timer_delete_sync (& iport -> fabric .fdmi_timer );
4977- iport -> fabric .fdmi_pending = 0 ;
5083+ if (fnic_fdmi_support == 1 ) {
5084+ if (iport -> fabric .fdmi_pending > 0 ) {
5085+ timer_delete_sync (& iport -> fabric .fdmi_timer );
5086+ iport -> fabric .fdmi_pending = 0 ;
5087+ }
5088+ iport -> flags &= ~FNIC_FDMI_ACTIVE ;
49785089 }
49795090
49805091 FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
0 commit comments