@@ -763,47 +763,69 @@ static void fdls_send_fabric_abts(struct fnic_iport_s *iport)
763
763
iport -> fabric .timer_pending = 1 ;
764
764
}
765
765
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 )
767
768
{
768
- uint8_t * frame ;
769
+ struct fc_frame_header * pfdmi_abts ;
769
770
uint8_t d_id [3 ];
771
+ uint8_t * frame ;
770
772
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 );
776
773
777
774
frame = fdls_alloc_frame (iport );
778
775
if (frame == NULL ) {
779
776
FNIC_FCS_DBG (KERN_ERR , fnic -> host , fnic -> fnic_num ,
780
777
"Failed to allocate frame to send FDMI ABTS" );
781
- return ;
778
+ return NULL ;
782
779
}
783
780
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 );
785
782
fdls_init_fabric_abts_frame (frame , iport );
786
783
787
784
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 );
789
797
790
798
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
+
793
804
fnic_send_fcoe_frame (iport , frame , frame_size );
794
805
} else {
795
806
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
+
798
812
fnic_send_fcoe_frame (iport , frame , frame_size );
799
813
}
800
814
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
+
803
824
fnic_send_fcoe_frame (iport , frame , frame_size );
804
825
}
805
826
}
806
827
828
+ arm_timer :
807
829
fdmi_tov = jiffies + msecs_to_jiffies (2 * iport -> e_d_tov );
808
830
mod_timer (& iport -> fabric .fdmi_timer , round_jiffies (fdmi_tov ));
809
831
iport -> fabric .fdmi_pending |= FDLS_FDMI_ABORT_PENDING ;
@@ -2245,6 +2267,21 @@ void fdls_fabric_timer_callback(struct timer_list *t)
2245
2267
spin_unlock_irqrestore (& fnic -> fnic_lock , flags );
2246
2268
}
2247
2269
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
+
2248
2285
void fdls_fdmi_timer_callback (struct timer_list * t )
2249
2286
{
2250
2287
struct fnic_fdls_fabric_s * fabric = timer_container_of (fabric , t ,
@@ -2291,14 +2328,7 @@ void fdls_fdmi_timer_callback(struct timer_list *t)
2291
2328
FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2292
2329
"fdmi timer callback : 0x%x\n" , iport -> fabric .fdmi_pending );
2293
2330
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 );
2302
2332
FNIC_FCS_DBG (KERN_INFO , fnic -> host , fnic -> fnic_num ,
2303
2333
"fdmi timer callback : 0x%x\n" , iport -> fabric .fdmi_pending );
2304
2334
spin_unlock_irqrestore (& fnic -> fnic_lock , flags );
@@ -3716,11 +3746,32 @@ static void fdls_process_fdmi_abts_rsp(struct fnic_iport_s *iport,
3716
3746
switch (FNIC_FRAME_TYPE (oxid )) {
3717
3747
case FNIC_FRAME_TYPE_FDMI_PLOGI :
3718
3748
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 ;
3719
3752
break ;
3720
3753
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
+
3721
3763
fdls_free_oxid (iport , oxid , & iport -> active_oxid_fdmi_rhba );
3722
3764
break ;
3723
3765
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
+
3724
3775
fdls_free_oxid (iport , oxid , & iport -> active_oxid_fdmi_rpa );
3725
3776
break ;
3726
3777
default :
@@ -3730,10 +3781,16 @@ static void fdls_process_fdmi_abts_rsp(struct fnic_iport_s *iport,
3730
3781
break ;
3731
3782
}
3732
3783
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
+ }
3737
3794
}
3738
3795
3739
3796
static void
0 commit comments