Skip to content

Commit 9cf9fe2

Browse files
Karan Tilak Kumarmartinkpetersen
authored andcommitted
scsi: fnic: Add functionality in fnic to support FDLS
Add interfaces in fnic to use FDLS services. Modify link up and link down functionality to use FDLS. Replace existing interfaces to handle new functionality provided by FDLS. Modify data types of some data members to handle new functionality. Add processing of tports and handling of tports. Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202409292037.ZYWZwIK6-lkp@intel.com/ Reviewed-by: Sesidhar Baddela <sebaddel@cisco.com> Co-developed-by: Gian Carlo Boffa <gcboffa@cisco.com> Signed-off-by: Gian Carlo Boffa <gcboffa@cisco.com> Co-developed-by: Arulprabhu Ponnusamy <arulponn@cisco.com> Signed-off-by: Arulprabhu Ponnusamy <arulponn@cisco.com> Co-developed-by: Arun Easi <aeasi@cisco.com> Signed-off-by: Arun Easi <aeasi@cisco.com> Co-developed-by: Karan Tilak Kumar <kartilak@cisco.com> Signed-off-by: Karan Tilak Kumar <kartilak@cisco.com> Link: https://lore.kernel.org/r/20241212020312.4786-10-kartilak@cisco.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 098585a commit 9cf9fe2

File tree

6 files changed

+568
-174
lines changed

6 files changed

+568
-174
lines changed

drivers/scsi/fnic/fdls_disc.c

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,13 @@ static bool fdls_is_oxid_tgt_req(uint16_t oxid)
397397
return true;
398398
}
399399

400+
static void fdls_reset_oxid_pool(struct fnic_iport_s *iport)
401+
{
402+
struct fnic_oxid_pool_s *oxid_pool = &iport->oxid_pool;
403+
404+
oxid_pool->next_idx = 0;
405+
}
406+
400407
void fnic_del_fabric_timer_sync(struct fnic *fnic)
401408
{
402409
fnic->iport.fabric.del_timer_inprogress = 1;
@@ -2248,7 +2255,6 @@ void fdls_fabric_timer_callback(struct timer_list *t)
22482255
}
22492256
break;
22502257
default:
2251-
fnic_fdls_start_flogi(iport); /* Placeholder call */
22522258
break;
22532259
}
22542260
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
@@ -3471,6 +3477,12 @@ fdls_process_flogi_rsp(struct fnic_iport_s *iport,
34713477

34723478
fnic_fdls_learn_fcoe_macs(iport, rx_frame, fcid);
34733479

3480+
if (fnic_fdls_register_portid(iport, iport->fcid, rx_frame) != 0) {
3481+
FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
3482+
"0x%x: FLOGI registration failed", iport->fcid);
3483+
break;
3484+
}
3485+
34743486
memcpy(&fcmac[3], fcid, 3);
34753487
FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
34763488
"Adding vNIC device MAC addr: %02x:%02x:%02x:%02x:%02x:%02x",
@@ -4448,6 +4460,30 @@ fdls_process_rscn(struct fnic_iport_s *iport, struct fc_frame_header *fchdr)
44484460
fdls_send_gpn_ft(iport, FDLS_STATE_RSCN_GPN_FT);
44494461
fdls_send_rscn_resp(iport, fchdr);
44504462
}
4463+
4464+
void fnic_fdls_disc_start(struct fnic_iport_s *iport)
4465+
{
4466+
struct fnic *fnic = iport->fnic;
4467+
4468+
if (IS_FNIC_FCP_INITIATOR(fnic)) {
4469+
fc_host_fabric_name(iport->fnic->lport->host) = 0;
4470+
fc_host_post_event(iport->fnic->lport->host, fc_get_event_number(),
4471+
FCH_EVT_LIPRESET, 0);
4472+
}
4473+
4474+
if (!iport->usefip) {
4475+
if (iport->flags & FNIC_FIRST_LINK_UP) {
4476+
spin_unlock_irqrestore(&fnic->fnic_lock, fnic->lock_flags);
4477+
fnic_scsi_fcpio_reset(iport->fnic);
4478+
spin_lock_irqsave(&fnic->fnic_lock, fnic->lock_flags);
4479+
4480+
iport->flags &= ~FNIC_FIRST_LINK_UP;
4481+
}
4482+
fnic_fdls_start_flogi(iport);
4483+
} else
4484+
fnic_fdls_start_plogi(iport);
4485+
}
4486+
44514487
static void
44524488
fdls_process_adisc_req(struct fnic_iport_s *iport,
44534489
struct fc_frame_header *fchdr)
@@ -4878,3 +4914,40 @@ void fnic_fdls_recv_frame(struct fnic_iport_s *iport, void *rx_frame,
48784914
break;
48794915
}
48804916
}
4917+
4918+
void fnic_fdls_disc_init(struct fnic_iport_s *iport)
4919+
{
4920+
fdls_reset_oxid_pool(iport);
4921+
fdls_set_state((&iport->fabric), FDLS_STATE_INIT);
4922+
}
4923+
4924+
void fnic_fdls_link_down(struct fnic_iport_s *iport)
4925+
{
4926+
struct fnic_tport_s *tport, *next;
4927+
struct fnic *fnic = iport->fnic;
4928+
4929+
FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
4930+
"0x%x: FDLS processing link down", iport->fcid);
4931+
4932+
fdls_set_state((&iport->fabric), FDLS_STATE_LINKDOWN);
4933+
iport->fabric.flags = 0;
4934+
4935+
if (IS_FNIC_FCP_INITIATOR(fnic)) {
4936+
spin_unlock_irqrestore(&fnic->fnic_lock, fnic->lock_flags);
4937+
fnic_scsi_fcpio_reset(iport->fnic);
4938+
spin_lock_irqsave(&fnic->fnic_lock, fnic->lock_flags);
4939+
list_for_each_entry_safe(tport, next, &iport->tport_list, links) {
4940+
FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
4941+
"removing rport: 0x%x", tport->fcid);
4942+
fdls_delete_tport(iport, tport);
4943+
}
4944+
}
4945+
4946+
if ((fnic_fdmi_support == 1) && (iport->fabric.fdmi_pending > 0)) {
4947+
del_timer_sync(&iport->fabric.fdmi_timer);
4948+
iport->fabric.fdmi_pending = 0;
4949+
}
4950+
4951+
FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
4952+
"0x%x: FDLS finish processing link down", iport->fcid);
4953+
}

drivers/scsi/fnic/fip.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,7 @@ void fnic_fcoe_process_flogi_resp(struct fnic *fnic, struct fip_header *fiph)
534534
FNIC_FIP_DBG(KERN_INFO, fnic->lport->host,
535535
fnic->fnic_num, "iport->state:%d\n",
536536
iport->state);
537+
fnic_fdls_disc_start(iport);
537538
if (!((iport->selected_fcf.ka_disabled)
538539
|| (iport->selected_fcf.fka_adv_period == 0))) {
539540
u64 tov;
@@ -617,6 +618,7 @@ void fnic_fcoe_process_cvl(struct fnic *fnic, struct fip_header *fiph)
617618
struct fip_cvl *cvl_msg = (struct fip_cvl *)fiph;
618619
int i;
619620
int found = false;
621+
int max_count = 0;
620622

621623
FNIC_FIP_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
622624
"fnic 0x%p clear virtual link handler\n", fnic);
@@ -658,6 +660,26 @@ void fnic_fcoe_process_cvl(struct fnic *fnic, struct fip_header *fiph)
658660
return;
659661
fnic_common_fip_cleanup(fnic);
660662

663+
while (fnic->reset_in_progress == IN_PROGRESS) {
664+
spin_unlock_irqrestore(&fnic->fnic_lock, fnic->lock_flags);
665+
wait_for_completion_timeout(&fnic->reset_completion_wait,
666+
msecs_to_jiffies(5000));
667+
spin_lock_irqsave(&fnic->fnic_lock, fnic->lock_flags);
668+
max_count++;
669+
if (max_count >= FIP_FNIC_RESET_WAIT_COUNT) {
670+
FNIC_FIP_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
671+
"Rthr waited too long. Skipping handle link event %p\n",
672+
fnic);
673+
return;
674+
}
675+
FNIC_FIP_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
676+
"fnic reset in progress. Link event needs to wait %p",
677+
fnic);
678+
}
679+
fnic->reset_in_progress = IN_PROGRESS;
680+
fnic_fdls_link_down(iport);
681+
fnic->reset_in_progress = NOT_IN_PROGRESS;
682+
complete(&fnic->reset_completion_wait);
661683
fnic_fcoe_send_vlan_req(fnic);
662684
}
663685
}
@@ -717,8 +739,10 @@ void fnic_work_on_fip_timer(struct work_struct *work)
717739
"FCF Discovery timeout\n");
718740
if (memcmp(iport->selected_fcf.fcf_mac, zmac, ETH_ALEN) != 0) {
719741

720-
if (iport->flags & FNIC_FIRST_LINK_UP)
742+
if (iport->flags & FNIC_FIRST_LINK_UP) {
743+
fnic_scsi_fcpio_reset(iport->fnic);
721744
iport->flags &= ~FNIC_FIRST_LINK_UP;
745+
}
722746

723747
fnic_fcoe_start_flogi(fnic);
724748
if (!((iport->selected_fcf.ka_disabled)
@@ -961,6 +985,7 @@ void fnic_work_on_fcs_ka_timer(struct work_struct *work)
961985

962986
fnic_common_fip_cleanup(fnic);
963987
spin_lock_irqsave(&fnic->fnic_lock, fnic->lock_flags);
988+
fnic_fdls_link_down(iport);
964989
iport->state = FNIC_IPORT_STATE_FIP;
965990
spin_unlock_irqrestore(&fnic->fnic_lock, fnic->lock_flags);
966991

drivers/scsi/fnic/fnic.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484

8585
#define IS_FNIC_FCP_INITIATOR(fnic) (fnic->role == FNIC_ROLE_FCP_INITIATOR)
8686

87+
#define FNIC_FW_RESET_TIMEOUT 60000 /* mSec */
8788
/* Retry supported by rport (returned by PRLI service parameters) */
8889
#define FNIC_FC_RP_FLAGS_RETRY 0x1
8990

@@ -205,6 +206,12 @@ static inline u64 fnic_flags_and_state(struct scsi_cmnd *cmd)
205206
#define fnic_clear_state_flags(fnicp, st_flags) \
206207
__fnic_set_state_flags(fnicp, st_flags, 1)
207208

209+
enum reset_states {
210+
NOT_IN_PROGRESS = 0,
211+
IN_PROGRESS,
212+
RESET_ERROR
213+
};
214+
208215
extern unsigned int fnic_fdmi_support;
209216
extern unsigned int fnic_log_level;
210217
extern unsigned int io_completions;
@@ -357,6 +364,7 @@ struct fnic {
357364
unsigned int wq_count;
358365
unsigned int cq_count;
359366

367+
struct completion reset_completion_wait;
360368
struct mutex sgreset_mutex;
361369
spinlock_t sgreset_lock; /* lock for sgreset */
362370
struct scsi_cmnd *sgreset_sc;
@@ -374,6 +382,8 @@ struct fnic {
374382

375383
struct completion *remove_wait; /* device remove thread blocks */
376384

385+
struct completion *fw_reset_done;
386+
u32 reset_in_progress;
377387
atomic_t in_flight; /* io counter */
378388
bool internal_reset_inprogress;
379389
u32 _reserved; /* fill hole */
@@ -387,6 +397,7 @@ struct fnic {
387397
u64 fcp_input_bytes; /* internal statistic */
388398
u64 fcp_output_bytes; /* internal statistic */
389399
u32 link_down_cnt;
400+
u32 soft_reset_count;
390401
int link_status;
391402

392403
struct list_head list;
@@ -409,7 +420,7 @@ struct fnic {
409420
struct work_struct link_work;
410421
struct work_struct frame_work;
411422
struct work_struct flush_work;
412-
struct sk_buff_head frame_queue;
423+
struct list_head frame_queue;
413424
struct list_head tx_queue;
414425
mempool_t *frame_pool;
415426
mempool_t *frame_elem_pool;
@@ -471,6 +482,7 @@ int fnic_request_intr(struct fnic *fnic);
471482
int fnic_send(struct fc_lport *, struct fc_frame *);
472483
void fnic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf);
473484
void fnic_handle_frame(struct work_struct *work);
485+
void fnic_tport_event_handler(struct work_struct *work);
474486
void fnic_handle_link(struct work_struct *work);
475487
void fnic_handle_event(struct work_struct *work);
476488
void fdls_reclaim_oxid_handler(struct work_struct *work);
@@ -485,7 +497,8 @@ void fnic_update_mac_locked(struct fnic *, u8 *new);
485497
int fnic_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
486498
int fnic_abort_cmd(struct scsi_cmnd *);
487499
int fnic_device_reset(struct scsi_cmnd *);
488-
int fnic_host_reset(struct scsi_cmnd *);
500+
int fnic_eh_host_reset_handler(struct scsi_cmnd *sc);
501+
int fnic_host_reset(struct Scsi_Host *shost);
489502
int fnic_reset(struct Scsi_Host *);
490503
void fnic_scsi_cleanup(struct fc_lport *);
491504
void fnic_scsi_abort_io(struct fc_lport *);
@@ -520,6 +533,9 @@ void fnic_dump_fchost_stats(struct Scsi_Host *, struct fc_host_statistics *);
520533
void fnic_free_txq(struct list_head *head);
521534
int fnic_get_desc_by_devid(struct pci_dev *pdev, char **desc,
522535
char **subsys_desc);
536+
void fnic_fdls_link_status_change(struct fnic *fnic, int linkup);
537+
void fnic_delete_fcp_tports(struct fnic *fnic);
538+
void fnic_flush_tport_event_list(struct fnic *fnic);
523539

524540
struct fnic_scsi_iter_data {
525541
struct fnic *fnic;

0 commit comments

Comments
 (0)