@@ -763,47 +763,69 @@ 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+ unsigned long fdmi_tov ;
795+ uint16_t frame_size = FNIC_ETH_FCOE_HDRS_OFFSET +
796+ sizeof (struct fc_frame_header );
789797
790798 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 );
799+ frame = fdls_alloc_init_fdmi_abts_frame (iport ,
800+ iport -> active_oxid_fdmi_plogi );
801+ if (frame == NULL )
802+ return ;
803+
793804 fnic_send_fcoe_frame (iport , frame , frame_size );
794805 } else {
795806 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 );
807+ frame = fdls_alloc_init_fdmi_abts_frame (iport ,
808+ iport -> active_oxid_fdmi_rhba );
809+ if (frame == NULL )
810+ return ;
811+
798812 fnic_send_fcoe_frame (iport , frame , frame_size );
799813 }
800814 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 );
815+ frame = fdls_alloc_init_fdmi_abts_frame (iport ,
816+ iport -> active_oxid_fdmi_rpa );
817+ if (frame == NULL ) {
818+ if (iport -> fabric .fdmi_pending & FDLS_FDMI_REG_HBA_PENDING )
819+ goto arm_timer ;
820+ else
821+ return ;
822+ }
823+
803824 fnic_send_fcoe_frame (iport , frame , frame_size );
804825 }
805826 }
806827
828+ arm_timer :
807829 fdmi_tov = jiffies + msecs_to_jiffies (2 * iport -> e_d_tov );
808830 mod_timer (& iport -> fabric .fdmi_timer , round_jiffies (fdmi_tov ));
809831 iport -> fabric .fdmi_pending |= FDLS_FDMI_ABORT_PENDING ;
@@ -2245,6 +2267,21 @@ void fdls_fabric_timer_callback(struct timer_list *t)
22452267 spin_unlock_irqrestore (& fnic -> fnic_lock , flags );
22462268}
22472269
2270+ void fdls_fdmi_retry_plogi (struct fnic_iport_s * iport )
2271+ {
2272+ struct fnic * fnic = iport -> fnic ;
2273+
2274+ iport -> fabric .fdmi_pending = 0 ;
2275+ /* If max retries not exhausted, start over from fdmi plogi */
2276+ if (iport -> fabric .fdmi_retry < FDLS_FDMI_MAX_RETRY ) {
2277+ iport -> fabric .fdmi_retry ++ ;
2278+ FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2279+ "Retry FDMI PLOGI. FDMI retry: %d" ,
2280+ iport -> fabric .fdmi_retry );
2281+ fdls_send_fdmi_plogi (iport );
2282+ }
2283+ }
2284+
22482285void fdls_fdmi_timer_callback (struct timer_list * t )
22492286{
22502287 struct fnic_fdls_fabric_s * fabric = timer_container_of (fabric , t ,
@@ -2291,14 +2328,7 @@ void fdls_fdmi_timer_callback(struct timer_list *t)
22912328 FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
22922329 "fdmi timer callback : 0x%x\n" , iport -> fabric .fdmi_pending );
22932330
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- }
2331+ fdls_fdmi_retry_plogi (iport );
23022332 FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
23032333 "fdmi timer callback : 0x%x\n" , iport -> fabric .fdmi_pending );
23042334 spin_unlock_irqrestore (& fnic -> fnic_lock , flags );
@@ -3716,11 +3746,32 @@ static void fdls_process_fdmi_abts_rsp(struct fnic_iport_s *iport,
37163746 switch (FNIC_FRAME_TYPE (oxid )) {
37173747 case FNIC_FRAME_TYPE_FDMI_PLOGI :
37183748 fdls_free_oxid (iport , oxid , & iport -> active_oxid_fdmi_plogi );
3749+
3750+ iport -> fabric .fdmi_pending &= ~FDLS_FDMI_PLOGI_PENDING ;
3751+ iport -> fabric .fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING ;
37193752 break ;
37203753 case FNIC_FRAME_TYPE_FDMI_RHBA :
3754+ iport -> fabric .fdmi_pending &= ~FDLS_FDMI_REG_HBA_PENDING ;
3755+
3756+ /* If RPA is still pending, don't turn off ABORT PENDING.
3757+ * We count on the timer to detect the ABTS timeout and take
3758+ * corrective action.
3759+ */
3760+ if (!(iport -> fabric .fdmi_pending & FDLS_FDMI_RPA_PENDING ))
3761+ iport -> fabric .fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING ;
3762+
37213763 fdls_free_oxid (iport , oxid , & iport -> active_oxid_fdmi_rhba );
37223764 break ;
37233765 case FNIC_FRAME_TYPE_FDMI_RPA :
3766+ iport -> fabric .fdmi_pending &= ~FDLS_FDMI_RPA_PENDING ;
3767+
3768+ /* If RHBA is still pending, don't turn off ABORT PENDING.
3769+ * We count on the timer to detect the ABTS timeout and take
3770+ * corrective action.
3771+ */
3772+ if (!(iport -> fabric .fdmi_pending & FDLS_FDMI_REG_HBA_PENDING ))
3773+ iport -> fabric .fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING ;
3774+
37243775 fdls_free_oxid (iport , oxid , & iport -> active_oxid_fdmi_rpa );
37253776 break ;
37263777 default :
@@ -3730,10 +3781,16 @@ static void fdls_process_fdmi_abts_rsp(struct fnic_iport_s *iport,
37303781 break ;
37313782 }
37323783
3733- timer_delete_sync (& iport -> fabric .fdmi_timer );
3734- iport -> fabric .fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING ;
3735-
3736- fdls_send_fdmi_plogi (iport );
3784+ /*
3785+ * Only if ABORT PENDING is off, delete the timer, and if no other
3786+ * operations are pending, retry FDMI.
3787+ * Otherwise, let the timer pop and take the appropriate action.
3788+ */
3789+ if (!(iport -> fabric .fdmi_pending & FDLS_FDMI_ABORT_PENDING )) {
3790+ timer_delete_sync (& iport -> fabric .fdmi_timer );
3791+ if (!iport -> fabric .fdmi_pending )
3792+ fdls_fdmi_retry_plogi (iport );
3793+ }
37373794}
37383795
37393796static void
0 commit comments