diff options
Diffstat (limited to 'drivers/scsi/qedf')
-rw-r--r-- | drivers/scsi/qedf/drv_fcoe_fw_funcs.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qedf/drv_fcoe_fw_funcs.h | 2 | ||||
-rw-r--r-- | drivers/scsi/qedf/drv_scsi_fw_funcs.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qedf/drv_scsi_fw_funcs.h | 2 | ||||
-rw-r--r-- | drivers/scsi/qedf/qedf.h | 6 | ||||
-rw-r--r-- | drivers/scsi/qedf/qedf_attr.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qedf/qedf_dbg.c | 4 | ||||
-rw-r--r-- | drivers/scsi/qedf/qedf_dbg.h | 2 | ||||
-rw-r--r-- | drivers/scsi/qedf/qedf_debugfs.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qedf/qedf_els.c | 35 | ||||
-rw-r--r-- | drivers/scsi/qedf/qedf_fip.c | 5 | ||||
-rw-r--r-- | drivers/scsi/qedf/qedf_hsi.h | 2 | ||||
-rw-r--r-- | drivers/scsi/qedf/qedf_io.c | 87 | ||||
-rw-r--r-- | drivers/scsi/qedf/qedf_main.c | 130 | ||||
-rw-r--r-- | drivers/scsi/qedf/qedf_version.h | 6 |
15 files changed, 238 insertions, 51 deletions
diff --git a/drivers/scsi/qedf/drv_fcoe_fw_funcs.c b/drivers/scsi/qedf/drv_fcoe_fw_funcs.c index a980ef756a67..5bd10b534c99 100644 --- a/drivers/scsi/qedf/drv_fcoe_fw_funcs.c +++ b/drivers/scsi/qedf/drv_fcoe_fw_funcs.c @@ -1,5 +1,5 @@ /* QLogic FCoE Offload Driver - * Copyright (c) 2016-2017 Cavium Inc. + * Copyright (c) 2016-2018 Cavium Inc. * * This software is available under the terms of the GNU General Public License * (GPL) Version 2, available from the file COPYING in the main directory of diff --git a/drivers/scsi/qedf/drv_fcoe_fw_funcs.h b/drivers/scsi/qedf/drv_fcoe_fw_funcs.h index b5c236efd465..42fde55ac735 100644 --- a/drivers/scsi/qedf/drv_fcoe_fw_funcs.h +++ b/drivers/scsi/qedf/drv_fcoe_fw_funcs.h @@ -1,5 +1,5 @@ /* QLogic FCoE Offload Driver - * Copyright (c) 2016-2017 Cavium Inc. + * Copyright (c) 2016-2018 Cavium Inc. * * This software is available under the terms of the GNU General Public License * (GPL) Version 2, available from the file COPYING in the main directory of diff --git a/drivers/scsi/qedf/drv_scsi_fw_funcs.c b/drivers/scsi/qedf/drv_scsi_fw_funcs.c index 5d5095e3d96d..29a55257224f 100644 --- a/drivers/scsi/qedf/drv_scsi_fw_funcs.c +++ b/drivers/scsi/qedf/drv_scsi_fw_funcs.c @@ -1,5 +1,5 @@ /* QLogic FCoE Offload Driver - * Copyright (c) 2016-2017 Cavium Inc. + * Copyright (c) 2016-2018 Cavium Inc. * * This software is available under the terms of the GNU General Public License * (GPL) Version 2, available from the file COPYING in the main directory of diff --git a/drivers/scsi/qedf/drv_scsi_fw_funcs.h b/drivers/scsi/qedf/drv_scsi_fw_funcs.h index 8fbe6e4d0b4f..bf102204fe56 100644 --- a/drivers/scsi/qedf/drv_scsi_fw_funcs.h +++ b/drivers/scsi/qedf/drv_scsi_fw_funcs.h @@ -1,5 +1,5 @@ /* QLogic FCoE Offload Driver - * Copyright (c) 2016-2017 Cavium Inc. + * Copyright (c) 2016-2018 Cavium Inc. * * This software is available under the terms of the GNU General Public License * (GPL) Version 2, available from the file COPYING in the main directory of diff --git a/drivers/scsi/qedf/qedf.h b/drivers/scsi/qedf/qedf.h index cabb6af60fb8..2c78d8fb9122 100644 --- a/drivers/scsi/qedf/qedf.h +++ b/drivers/scsi/qedf/qedf.h @@ -1,6 +1,6 @@ /* * QLogic FCoE Offload Driver - * Copyright (c) 2016-2017 Cavium Inc. + * Copyright (c) 2016-2018 Cavium Inc. * * This software is available under the terms of the GNU General Public License * (GPL) Version 2, available from the file COPYING in the main directory of @@ -180,6 +180,7 @@ struct qedf_rport { spinlock_t rport_lock; #define QEDF_RPORT_SESSION_READY 1 #define QEDF_RPORT_UPLOADING_CONNECTION 2 +#define QEDF_RPORT_IN_RESET 3 unsigned long flags; unsigned long retry_delay_timestamp; struct fc_rport *rport; @@ -300,6 +301,7 @@ struct qedf_ctx { #define QEDF_FALLBACK_VLAN 1002 #define QEDF_DEFAULT_PRIO 3 int vlan_id; + u8 prio; struct qed_dev *cdev; struct qed_dev_fcoe_info dev_info; struct qed_int_info int_info; @@ -365,6 +367,7 @@ struct qedf_ctx { #define QEDF_IO_WORK_MIN 64 mempool_t *io_mempool; struct workqueue_struct *dpc_wq; + struct delayed_work grcdump_work; u32 slow_sge_ios; u32 fast_sge_ios; @@ -504,6 +507,7 @@ extern int qedf_send_flogi(struct qedf_ctx *qedf); extern void qedf_get_protocol_tlv_data(void *dev, void *data); extern void qedf_fp_io_handler(struct work_struct *work); extern void qedf_get_generic_tlv_data(void *dev, struct qed_generic_tlvs *data); +extern void qedf_wq_grcdump(struct work_struct *work); #define FCOE_WORD_TO_BYTE 4 #define QEDF_MAX_TASK_NUM 0xFFFF diff --git a/drivers/scsi/qedf/qedf_attr.c b/drivers/scsi/qedf/qedf_attr.c index fa6727685627..0487b7237104 100644 --- a/drivers/scsi/qedf/qedf_attr.c +++ b/drivers/scsi/qedf/qedf_attr.c @@ -1,6 +1,6 @@ /* * QLogic FCoE Offload Driver - * Copyright (c) 2016-2017 Cavium Inc. + * Copyright (c) 2016-2018 Cavium Inc. * * This software is available under the terms of the GNU General Public License * (GPL) Version 2, available from the file COPYING in the main directory of diff --git a/drivers/scsi/qedf/qedf_dbg.c b/drivers/scsi/qedf/qedf_dbg.c index bd1cef25a900..f2397ee9ba69 100644 --- a/drivers/scsi/qedf/qedf_dbg.c +++ b/drivers/scsi/qedf/qedf_dbg.c @@ -1,6 +1,6 @@ /* * QLogic FCoE Offload Driver - * Copyright (c) 2016 Cavium Inc. + * Copyright (c) 2016-2018 Cavium Inc. * * This software is available under the terms of the GNU General Public License * (GPL) Version 2, available from the file COPYING in the main directory of @@ -147,7 +147,7 @@ qedf_get_grc_dump(struct qed_dev *cdev, const struct qed_common_ops *common, if (!*buf) return -EINVAL; - return common->dbg_grc(cdev, *buf, grcsize); + return common->dbg_all_data(cdev, *buf); } void diff --git a/drivers/scsi/qedf/qedf_dbg.h b/drivers/scsi/qedf/qedf_dbg.h index 77c27e888969..dd0109653aa3 100644 --- a/drivers/scsi/qedf/qedf_dbg.h +++ b/drivers/scsi/qedf/qedf_dbg.h @@ -1,6 +1,6 @@ /* * QLogic FCoE Offload Driver - * Copyright (c) 2016-2017 Cavium Inc. + * Copyright (c) 2016-2018 Cavium Inc. * * This software is available under the terms of the GNU General Public License * (GPL) Version 2, available from the file COPYING in the main directory of diff --git a/drivers/scsi/qedf/qedf_debugfs.c b/drivers/scsi/qedf/qedf_debugfs.c index 5789ce185923..c29c162a494f 100644 --- a/drivers/scsi/qedf/qedf_debugfs.c +++ b/drivers/scsi/qedf/qedf_debugfs.c @@ -1,6 +1,6 @@ /* * QLogic FCoE Offload Driver - * Copyright (c) 2016-2017 QLogic Corporation + * Copyright (c) 2016-2018 QLogic Corporation * * This software is available under the terms of the GNU General Public License * (GPL) Version 2, available from the file COPYING in the main directory of diff --git a/drivers/scsi/qedf/qedf_els.c b/drivers/scsi/qedf/qedf_els.c index aa22b11436ba..04f0c4d2e256 100644 --- a/drivers/scsi/qedf/qedf_els.c +++ b/drivers/scsi/qedf/qedf_els.c @@ -1,6 +1,6 @@ /* * QLogic FCoE Offload Driver - * Copyright (c) 2016-2017 Cavium Inc. + * Copyright (c) 2016-2018 Cavium Inc. * * This software is available under the terms of the GNU General Public License * (GPL) Version 2, available from the file COPYING in the main directory of @@ -14,8 +14,8 @@ static int qedf_initiate_els(struct qedf_rport *fcport, unsigned int op, void (*cb_func)(struct qedf_els_cb_arg *cb_arg), struct qedf_els_cb_arg *cb_arg, uint32_t timer_msec) { - struct qedf_ctx *qedf = fcport->qedf; - struct fc_lport *lport = qedf->lport; + struct qedf_ctx *qedf; + struct fc_lport *lport; struct qedf_ioreq *els_req; struct qedf_mp_req *mp_req; struct fc_frame_header *fc_hdr; @@ -29,6 +29,15 @@ static int qedf_initiate_els(struct qedf_rport *fcport, unsigned int op, unsigned long flags; u16 sqe_idx; + if (!fcport) { + QEDF_ERR(NULL, "fcport is NULL"); + rc = -EINVAL; + goto els_err; + } + + qedf = fcport->qedf; + lport = qedf->lport; + QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "Sending ELS\n"); rc = fc_remote_port_chkready(fcport->rport); @@ -201,6 +210,14 @@ static void qedf_rrq_compl(struct qedf_els_cb_arg *cb_arg) kref_put(&orig_io_req->refcount, qedf_release_cmd); out_free: + /* + * Release a reference to the rrq request if we timed out as the + * rrq completion handler is called directly from the timeout handler + * and not from els_compl where the reference would have normally been + * released. + */ + if (rrq_req->event == QEDF_IOREQ_EV_ELS_TMO) + kref_put(&rrq_req->refcount, qedf_release_cmd); kfree(cb_arg); } @@ -322,6 +339,17 @@ void qedf_restart_rport(struct qedf_rport *fcport) if (!fcport) return; + if (test_bit(QEDF_RPORT_IN_RESET, &fcport->flags) || + !test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags) || + test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) { + QEDF_ERR(&(fcport->qedf->dbg_ctx), "fcport %p already in reset or not offloaded.\n", + fcport); + return; + } + + /* Set that we are now in reset */ + set_bit(QEDF_RPORT_IN_RESET, &fcport->flags); + rdata = fcport->rdata; if (rdata) { lport = fcport->qedf->lport; @@ -334,6 +362,7 @@ void qedf_restart_rport(struct qedf_rport *fcport) if (rdata) fc_rport_login(rdata); } + clear_bit(QEDF_RPORT_IN_RESET, &fcport->flags); } static void qedf_l2_els_compl(struct qedf_els_cb_arg *cb_arg) diff --git a/drivers/scsi/qedf/qedf_fip.c b/drivers/scsi/qedf/qedf_fip.c index 16d1a21cdff9..3fd3af799b3d 100644 --- a/drivers/scsi/qedf/qedf_fip.c +++ b/drivers/scsi/qedf/qedf_fip.c @@ -1,6 +1,6 @@ /* * QLogic FCoE Offload Driver - * Copyright (c) 2016-2017 Cavium Inc. + * Copyright (c) 2016-2018 Cavium Inc. * * This software is available under the terms of the GNU General Public License * (GPL) Version 2, available from the file COPYING in the main directory of @@ -137,7 +137,7 @@ void qedf_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb) QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2, "FIP frame send: " "dest=%pM op=%x sub=%x vlan=%04x.", eth_hdr->h_dest, op, sub, - ntohs(vlan_tci)); + vlan_tci); if (qedf_dump_frames) print_hex_dump(KERN_WARNING, "fip ", DUMP_PREFIX_OFFSET, 16, 1, skb->data, skb->len, false); @@ -184,6 +184,7 @@ void qedf_fip_recv(struct qedf_ctx *qedf, struct sk_buff *skb) QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, "Dropping CVL since FCF has not been selected " "yet."); + kfree_skb(skb); return; } diff --git a/drivers/scsi/qedf/qedf_hsi.h b/drivers/scsi/qedf/qedf_hsi.h index 503c1ae3ccd0..f6f634e48d69 100644 --- a/drivers/scsi/qedf/qedf_hsi.h +++ b/drivers/scsi/qedf/qedf_hsi.h @@ -1,6 +1,6 @@ /* * QLogic FCoE Offload Driver - * Copyright (c) 2016-2017 Cavium Inc. + * Copyright (c) 2016-2018 Cavium Inc. * * This software is available under the terms of the GNU General Public License * (GPL) Version 2, available from the file COPYING in the main directory of diff --git a/drivers/scsi/qedf/qedf_io.c b/drivers/scsi/qedf/qedf_io.c index 3fe579d0f1a8..6bbc38b1b465 100644 --- a/drivers/scsi/qedf/qedf_io.c +++ b/drivers/scsi/qedf/qedf_io.c @@ -1,6 +1,6 @@ /* * QLogic FCoE Offload Driver - * Copyright (c) 2016-2017 Cavium Inc. + * Copyright (c) 2016-2018 Cavium Inc. * * This software is available under the terms of the GNU General Public License * (GPL) Version 2, available from the file COPYING in the main directory of @@ -23,12 +23,31 @@ static void qedf_cmd_timeout(struct work_struct *work) struct qedf_ioreq *io_req = container_of(work, struct qedf_ioreq, timeout_work.work); - struct qedf_ctx *qedf = io_req->fcport->qedf; - struct qedf_rport *fcport = io_req->fcport; + struct qedf_ctx *qedf; + struct qedf_rport *fcport; u8 op = 0; + if (io_req == NULL) { + QEDF_INFO(NULL, QEDF_LOG_IO, "io_req is NULL.\n"); + return; + } + + fcport = io_req->fcport; + if (io_req->fcport == NULL) { + QEDF_INFO(NULL, QEDF_LOG_IO, "fcport is NULL.\n"); + return; + } + + qedf = fcport->qedf; + switch (io_req->cmd_type) { case QEDF_ABTS: + if (qedf == NULL) { + QEDF_INFO(NULL, QEDF_LOG_IO, "qedf is NULL for xid=0x%x.\n", + io_req->xid); + return; + } + QEDF_ERR((&qedf->dbg_ctx), "ABTS timeout, xid=0x%x.\n", io_req->xid); /* Cleanup timed out ABTS */ @@ -931,6 +950,15 @@ qedf_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc_cmd) return 0; } + if (!qedf->pdev->msix_enabled) { + QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO, + "Completing sc_cmd=%p DID_NO_CONNECT as MSI-X is not enabled.\n", + sc_cmd); + sc_cmd->result = DID_NO_CONNECT << 16; + sc_cmd->scsi_done(sc_cmd); + return 0; + } + rval = fc_remote_port_chkready(rport); if (rval) { sc_cmd->result = rval; @@ -1420,6 +1448,12 @@ void qedf_flush_active_ios(struct qedf_rport *fcport, int lun) if (!fcport) return; + /* Check that fcport is still offloaded */ + if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) { + QEDF_ERR(NULL, "fcport is no longer offloaded.\n"); + return; + } + qedf = fcport->qedf; cmd_mgr = qedf->cmd_mgr; @@ -1436,8 +1470,8 @@ void qedf_flush_active_ios(struct qedf_rport *fcport, int lun) rc = kref_get_unless_zero(&io_req->refcount); if (!rc) { QEDF_ERR(&(qedf->dbg_ctx), - "Could not get kref for io_req=0x%p.\n", - io_req); + "Could not get kref for ELS io_req=0x%p xid=0x%x.\n", + io_req, io_req->xid); continue; } qedf_flush_els_req(qedf, io_req); @@ -1448,6 +1482,31 @@ void qedf_flush_active_ios(struct qedf_rport *fcport, int lun) goto free_cmd; } + if (io_req->cmd_type == QEDF_ABTS) { + rc = kref_get_unless_zero(&io_req->refcount); + if (!rc) { + QEDF_ERR(&(qedf->dbg_ctx), + "Could not get kref for abort io_req=0x%p xid=0x%x.\n", + io_req, io_req->xid); + continue; + } + QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, + "Flushing abort xid=0x%x.\n", io_req->xid); + + clear_bit(QEDF_CMD_IN_ABORT, &io_req->flags); + + if (io_req->sc_cmd) { + if (io_req->return_scsi_cmd_on_abts) + qedf_scsi_done(qedf, io_req, DID_ERROR); + } + + /* Notify eh_abort handler that ABTS is complete */ + complete(&io_req->abts_done); + kref_put(&io_req->refcount, qedf_release_cmd); + + goto free_cmd; + } + if (!io_req->sc_cmd) continue; if (lun > 0) { @@ -1463,7 +1522,7 @@ void qedf_flush_active_ios(struct qedf_rport *fcport, int lun) rc = kref_get_unless_zero(&io_req->refcount); if (!rc) { QEDF_ERR(&(qedf->dbg_ctx), "Could not get kref for " - "io_req=0x%p\n", io_req); + "io_req=0x%p xid=0x%x\n", io_req, io_req->xid); continue; } QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO, @@ -1525,6 +1584,21 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts) goto abts_err; } + if (test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) { + QEDF_ERR(&qedf->dbg_ctx, "fcport is uploading.\n"); + rc = 1; + goto out; + } + + if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) || + test_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags) || + test_bit(QEDF_CMD_IN_ABORT, &io_req->flags)) { + QEDF_ERR(&(qedf->dbg_ctx), "io_req xid=0x%x already in " + "cleanup or abort processing or already " + "completed.\n", io_req->xid); + rc = 1; + goto out; + } kref_get(&io_req->refcount); @@ -1564,6 +1638,7 @@ abts_err: * task at the firmware. */ qedf_initiate_cleanup(io_req, return_scsi_cmd_on_abts); +out: return rc; } diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index d3f73d8d7738..90394cef0f41 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -1,6 +1,6 @@ /* * QLogic FCoE Offload Driver - * Copyright (c) 2016-2017 Cavium Inc. + * Copyright (c) 2016-2018 Cavium Inc. * * This software is available under the terms of the GNU General Public License * (GPL) Version 2, available from the file COPYING in the main directory of @@ -44,20 +44,20 @@ module_param_named(debug, qedf_debug, uint, S_IRUGO); MODULE_PARM_DESC(debug, " Debug mask. Pass '1' to enable default debugging" " mask"); -static uint qedf_fipvlan_retries = 30; +static uint qedf_fipvlan_retries = 60; module_param_named(fipvlan_retries, qedf_fipvlan_retries, int, S_IRUGO); MODULE_PARM_DESC(fipvlan_retries, " Number of FIP VLAN requests to attempt " - "before giving up (default 30)"); + "before giving up (default 60)"); static uint qedf_fallback_vlan = QEDF_FALLBACK_VLAN; module_param_named(fallback_vlan, qedf_fallback_vlan, int, S_IRUGO); MODULE_PARM_DESC(fallback_vlan, " VLAN ID to try if fip vlan request fails " "(default 1002)."); -static uint qedf_default_prio = QEDF_DEFAULT_PRIO; +static int qedf_default_prio = -1; module_param_named(default_prio, qedf_default_prio, int, S_IRUGO); -MODULE_PARM_DESC(default_prio, " Default 802.1q priority for FIP and FCoE" - " traffic (default 3)."); +MODULE_PARM_DESC(default_prio, " Override 802.1q priority for FIP and FCoE" + " traffic (value between 0 and 7, default 3)."); uint qedf_dump_frames; module_param_named(dump_frames, qedf_dump_frames, int, S_IRUGO | S_IWUSR); @@ -89,6 +89,11 @@ module_param_named(retry_delay, qedf_retry_delay, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(retry_delay, " Enable/disable handling of FCP_RSP IU retry " "delay handling (default off)."); +static bool qedf_dcbx_no_wait; +module_param_named(dcbx_no_wait, qedf_dcbx_no_wait, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(dcbx_no_wait, " Do not wait for DCBX convergence to start " + "sending FIP VLAN requests on link up (Default: off)."); + static uint qedf_dp_module; module_param_named(dp_module, qedf_dp_module, uint, S_IRUGO); MODULE_PARM_DESC(dp_module, " bit flags control for verbose printk passed " @@ -109,9 +114,9 @@ static struct kmem_cache *qedf_io_work_cache; void qedf_set_vlan_id(struct qedf_ctx *qedf, int vlan_id) { qedf->vlan_id = vlan_id; - qedf->vlan_id |= qedf_default_prio << VLAN_PRIO_SHIFT; + qedf->vlan_id |= qedf->prio << VLAN_PRIO_SHIFT; QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, "Setting vlan_id=%04x " - "prio=%d.\n", vlan_id, qedf_default_prio); + "prio=%d.\n", vlan_id, qedf->prio); } /* Returns true if we have a valid vlan, false otherwise */ @@ -480,6 +485,11 @@ static void qedf_link_update(void *dev, struct qed_link_output *link) struct qedf_ctx *qedf = (struct qedf_ctx *)dev; if (link->link_up) { + if (atomic_read(&qedf->link_state) == QEDF_LINK_UP) { + QEDF_INFO((&qedf->dbg_ctx), QEDF_LOG_DISC, + "Ignoring link up event as link is already up.\n"); + return; + } QEDF_ERR(&(qedf->dbg_ctx), "LINK UP (%d GB/s).\n", link->speed / 1000); @@ -489,7 +499,8 @@ static void qedf_link_update(void *dev, struct qed_link_output *link) atomic_set(&qedf->link_state, QEDF_LINK_UP); qedf_update_link_speed(qedf, link); - if (atomic_read(&qedf->dcbx) == QEDF_DCBX_DONE) { + if (atomic_read(&qedf->dcbx) == QEDF_DCBX_DONE || + qedf_dcbx_no_wait) { QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, "DCBx done.\n"); if (atomic_read(&qedf->link_down_tmo_valid) > 0) @@ -515,7 +526,7 @@ static void qedf_link_update(void *dev, struct qed_link_output *link) "Starting link down tmo.\n"); atomic_set(&qedf->link_down_tmo_valid, 1); } - qedf->vlan_id = 0; + qedf->vlan_id = 0; qedf_update_link_speed(qedf, link); queue_delayed_work(qedf->link_update_wq, &qedf->link_update, qedf_link_down_tmo * HZ); @@ -526,6 +537,7 @@ static void qedf_link_update(void *dev, struct qed_link_output *link) static void qedf_dcbx_handler(void *dev, struct qed_dcbx_get *get, u32 mib_type) { struct qedf_ctx *qedf = (struct qedf_ctx *)dev; + u8 tmp_prio; QEDF_ERR(&(qedf->dbg_ctx), "DCBx event valid=%d enabled=%d fcoe " "prio=%d.\n", get->operational.valid, get->operational.enabled, @@ -541,7 +553,26 @@ static void qedf_dcbx_handler(void *dev, struct qed_dcbx_get *get, u32 mib_type) atomic_set(&qedf->dcbx, QEDF_DCBX_DONE); - if (atomic_read(&qedf->link_state) == QEDF_LINK_UP) { + /* + * Set the 8021q priority in the following manner: + * + * 1. If a modparam is set use that + * 2. If the value is not between 0..7 use the default + * 3. Use the priority we get from the DCBX app tag + */ + tmp_prio = get->operational.app_prio.fcoe; + if (qedf_default_prio > -1) + qedf->prio = qedf_default_prio; + else if (tmp_prio < 0 || tmp_prio > 7) { + QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, + "FIP/FCoE prio %d out of range, setting to %d.\n", + tmp_prio, QEDF_DEFAULT_PRIO); + qedf->prio = QEDF_DEFAULT_PRIO; + } else + qedf->prio = tmp_prio; + + if (atomic_read(&qedf->link_state) == QEDF_LINK_UP && + !qedf_dcbx_no_wait) { if (atomic_read(&qedf->link_down_tmo_valid) > 0) queue_delayed_work(qedf->link_update_wq, &qedf->link_recovery, 0); @@ -614,16 +645,6 @@ static int qedf_eh_abort(struct scsi_cmnd *sc_cmd) goto out; } - if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) || - test_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags) || - test_bit(QEDF_CMD_IN_ABORT, &io_req->flags)) { - QEDF_ERR(&(qedf->dbg_ctx), "io_req xid=0x%x already in " - "cleanup or abort processing or already " - "completed.\n", io_req->xid); - rc = SUCCESS; - goto out; - } - QEDF_ERR(&(qedf->dbg_ctx), "Aborting io_req sc_cmd=%p xid=0x%x " "fp_idx=%d.\n", sc_cmd, io_req->xid, io_req->fp_idx); @@ -705,7 +726,6 @@ static void qedf_ctx_soft_reset(struct fc_lport *lport) /* For host reset, essentially do a soft link up/down */ atomic_set(&qedf->link_state, QEDF_LINK_DOWN); - atomic_set(&qedf->dcbx, QEDF_DCBX_PENDING); queue_delayed_work(qedf->link_update_wq, &qedf->link_update, 0); qedf_wait_for_upload(qedf); @@ -720,6 +740,22 @@ static int qedf_eh_host_reset(struct scsi_cmnd *sc_cmd) { struct fc_lport *lport; struct qedf_ctx *qedf; + struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device)); + struct fc_rport_libfc_priv *rp = rport->dd_data; + struct qedf_rport *fcport = (struct qedf_rport *)&rp[1]; + int rval; + + rval = fc_remote_port_chkready(rport); + + if (rval) { + QEDF_ERR(NULL, "device_reset rport not ready\n"); + return FAILED; + } + + if (fcport == NULL) { + QEDF_ERR(NULL, "device_reset: rport is NULL\n"); + return FAILED; + } lport = shost_priv(sc_cmd->device->host); qedf = lport_priv(lport); @@ -1109,7 +1145,7 @@ static int qedf_offload_connection(struct qedf_ctx *qedf, conn_info.vlan_tag = qedf->vlan_id << FCOE_CONN_OFFLOAD_RAMROD_DATA_VLAN_ID_SHIFT; conn_info.vlan_tag |= - qedf_default_prio << FCOE_CONN_OFFLOAD_RAMROD_DATA_PRIORITY_SHIFT; + qedf->prio << FCOE_CONN_OFFLOAD_RAMROD_DATA_PRIORITY_SHIFT; conn_info.flags |= (FCOE_CONN_OFFLOAD_RAMROD_DATA_B_VLAN_FLAG_MASK << FCOE_CONN_OFFLOAD_RAMROD_DATA_B_VLAN_FLAG_SHIFT); @@ -1649,6 +1685,15 @@ static int qedf_vport_destroy(struct fc_vport *vport) struct Scsi_Host *shost = vport_to_shost(vport); struct fc_lport *n_port = shost_priv(shost); struct fc_lport *vn_port = vport->dd_data; + struct qedf_ctx *qedf = lport_priv(vn_port); + + if (!qedf) { + QEDF_ERR(NULL, "qedf is NULL.\n"); + goto out; + } + + /* Set unloading bit on vport qedf_ctx to prevent more I/O */ + set_bit(QEDF_UNLOADING, &qedf->flags); mutex_lock(&n_port->lp_mutex); list_del(&vn_port->list); @@ -1675,6 +1720,7 @@ static int qedf_vport_destroy(struct fc_vport *vport) if (vn_port->host) scsi_host_put(vn_port->host); +out: return 0; } @@ -2109,7 +2155,8 @@ static int qedf_setup_int(struct qedf_ctx *qedf) QEDF_SIMD_HANDLER_NUM, qedf_simd_int_handler); qedf->int_info.used_cnt = 1; - return 0; + QEDF_ERR(&qedf->dbg_ctx, "Only MSI-X supported. Failing probe.\n"); + return -EINVAL; } /* Main function for libfc frame reception */ @@ -2195,6 +2242,7 @@ static void qedf_recv_frame(struct qedf_ctx *qedf, if (ntoh24(&dest_mac[3]) != ntoh24(fh->fh_d_id)) { QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2, "FC frame d_id mismatch with MAC %pM.\n", dest_mac); + kfree_skb(skb); return; } @@ -2983,8 +3031,17 @@ static int __qedf_probe(struct pci_dev *pdev, int mode) qedf->link_update_wq = create_workqueue(host_buf); INIT_DELAYED_WORK(&qedf->link_update, qedf_handle_link_update); INIT_DELAYED_WORK(&qedf->link_recovery, qedf_link_recovery); - + INIT_DELAYED_WORK(&qedf->grcdump_work, qedf_wq_grcdump); qedf->fipvlan_retries = qedf_fipvlan_retries; + /* Set a default prio in case DCBX doesn't converge */ + if (qedf_default_prio > -1) { + /* + * This is the case where we pass a modparam in so we want to + * honor it even if dcbx doesn't converge. + */ + qedf->prio = qedf_default_prio; + } else + qedf->prio = QEDF_DEFAULT_PRIO; /* * Common probe. Takes care of basic hardware init and pci_* @@ -3214,7 +3271,8 @@ static int __qedf_probe(struct pci_dev *pdev, int mode) * unload process. */ if (mode != QEDF_MODE_RECOVERY) { - qedf->grcdump_size = qed_ops->common->dbg_grc_size(qedf->cdev); + qedf->grcdump_size = + qed_ops->common->dbg_all_data_size(qedf->cdev); if (qedf->grcdump_size) { rc = qedf_alloc_grc_dump_buf(&qedf->grcdump, qedf->grcdump_size); @@ -3398,6 +3456,15 @@ static void qedf_remove(struct pci_dev *pdev) __qedf_remove(pdev, QEDF_MODE_NORMAL); } +void qedf_wq_grcdump(struct work_struct *work) +{ + struct qedf_ctx *qedf = + container_of(work, struct qedf_ctx, grcdump_work.work); + + QEDF_ERR(&(qedf->dbg_ctx), "Collecting GRC dump.\n"); + qedf_capture_grc_dump(qedf); +} + /* * Protocol TLV handler */ @@ -3508,6 +3575,17 @@ static int __init qedf_init(void) if (qedf_debug == QEDF_LOG_DEFAULT) qedf_debug = QEDF_DEFAULT_LOG_MASK; + /* + * Check that default prio for FIP/FCoE traffic is between 0..7 if a + * value has been set + */ + if (qedf_default_prio > -1) + if (qedf_default_prio > 7) { + qedf_default_prio = QEDF_DEFAULT_PRIO; + QEDF_ERR(NULL, "FCoE/FIP priority out of range, resetting to %d.\n", + QEDF_DEFAULT_PRIO); + } + /* Print driver banner */ QEDF_INFO(NULL, QEDF_LOG_INFO, "%s v%s.\n", QEDF_DESCR, QEDF_VERSION); diff --git a/drivers/scsi/qedf/qedf_version.h b/drivers/scsi/qedf/qedf_version.h index c2478056356a..9455faacd5de 100644 --- a/drivers/scsi/qedf/qedf_version.h +++ b/drivers/scsi/qedf/qedf_version.h @@ -1,15 +1,15 @@ /* * QLogic FCoE Offload Driver - * Copyright (c) 2016-2017 Cavium Inc. + * Copyright (c) 2016-2018 Cavium Inc. * * This software is available under the terms of the GNU General Public License * (GPL) Version 2, available from the file COPYING in the main directory of * this source tree. */ -#define QEDF_VERSION "8.33.0.20" +#define QEDF_VERSION "8.33.16.20" #define QEDF_DRIVER_MAJOR_VER 8 #define QEDF_DRIVER_MINOR_VER 33 -#define QEDF_DRIVER_REV_VER 0 +#define QEDF_DRIVER_REV_VER 16 #define QEDF_DRIVER_ENG_VER 20 |