summaryrefslogtreecommitdiff
path: root/drivers/scsi/qedf
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qedf')
-rw-r--r--drivers/scsi/qedf/drv_fcoe_fw_funcs.c2
-rw-r--r--drivers/scsi/qedf/drv_fcoe_fw_funcs.h2
-rw-r--r--drivers/scsi/qedf/drv_scsi_fw_funcs.c2
-rw-r--r--drivers/scsi/qedf/drv_scsi_fw_funcs.h2
-rw-r--r--drivers/scsi/qedf/qedf.h2
-rw-r--r--drivers/scsi/qedf/qedf_attr.c59
-rw-r--r--drivers/scsi/qedf/qedf_dbg.h2
-rw-r--r--drivers/scsi/qedf/qedf_debugfs.c2
-rw-r--r--drivers/scsi/qedf/qedf_els.c8
-rw-r--r--drivers/scsi/qedf/qedf_fip.c25
-rw-r--r--drivers/scsi/qedf/qedf_hsi.h2
-rw-r--r--drivers/scsi/qedf/qedf_io.c37
-rw-r--r--drivers/scsi/qedf/qedf_main.c209
-rw-r--r--drivers/scsi/qedf/qedf_version.h8
14 files changed, 251 insertions, 111 deletions
diff --git a/drivers/scsi/qedf/drv_fcoe_fw_funcs.c b/drivers/scsi/qedf/drv_fcoe_fw_funcs.c
index 8c65e3b034dc..7d91e53562f8 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 Cavium Inc.
+ * Copyright (c) 2016-2017 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 617529b058f4..f9c50faa748e 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 Cavium Inc.
+ * Copyright (c) 2016-2017 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 11e0cc082ec0..5d5095e3d96d 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 Cavium Inc.
+ * Copyright (c) 2016-2017 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 9cb45410bc45..8fbe6e4d0b4f 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 Cavium Inc.
+ * Copyright (c) 2016-2017 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 07ee88200e91..4d038926a455 100644
--- a/drivers/scsi/qedf/qedf.h
+++ b/drivers/scsi/qedf/qedf.h
@@ -1,6 +1,6 @@
/*
* QLogic FCoE Offload Driver
- * Copyright (c) 2016 Cavium Inc.
+ * Copyright (c) 2016-2017 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_attr.c b/drivers/scsi/qedf/qedf_attr.c
index 47720611ad2c..fa6727685627 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 Cavium Inc.
+ * Copyright (c) 2016-2017 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
@@ -8,6 +8,25 @@
*/
#include "qedf.h"
+inline bool qedf_is_vport(struct qedf_ctx *qedf)
+{
+ return qedf->lport->vport != NULL;
+}
+
+/* Get base qedf for physical port from vport */
+static struct qedf_ctx *qedf_get_base_qedf(struct qedf_ctx *qedf)
+{
+ struct fc_lport *lport;
+ struct fc_lport *base_lport;
+
+ if (!(qedf_is_vport(qedf)))
+ return NULL;
+
+ lport = qedf->lport;
+ base_lport = shost_priv(vport_to_shost(lport->vport));
+ return lport_priv(base_lport);
+}
+
static ssize_t
qedf_fcoe_mac_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -26,34 +45,34 @@ qedf_fcoe_mac_show(struct device *dev,
return scnprintf(buf, PAGE_SIZE, "%pM\n", fcoe_mac);
}
+static ssize_t
+qedf_fka_period_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fc_lport *lport = shost_priv(class_to_shost(dev));
+ struct qedf_ctx *qedf = lport_priv(lport);
+ int fka_period = -1;
+
+ if (qedf_is_vport(qedf))
+ qedf = qedf_get_base_qedf(qedf);
+
+ if (qedf->ctlr.sel_fcf)
+ fka_period = qedf->ctlr.sel_fcf->fka_period;
+
+ return scnprintf(buf, PAGE_SIZE, "%d\n", fka_period);
+}
+
static DEVICE_ATTR(fcoe_mac, S_IRUGO, qedf_fcoe_mac_show, NULL);
+static DEVICE_ATTR(fka_period, S_IRUGO, qedf_fka_period_show, NULL);
struct device_attribute *qedf_host_attrs[] = {
&dev_attr_fcoe_mac,
+ &dev_attr_fka_period,
NULL,
};
extern const struct qed_fcoe_ops *qed_ops;
-inline bool qedf_is_vport(struct qedf_ctx *qedf)
-{
- return (!(qedf->lport->vport == NULL));
-}
-
-/* Get base qedf for physical port from vport */
-static struct qedf_ctx *qedf_get_base_qedf(struct qedf_ctx *qedf)
-{
- struct fc_lport *lport;
- struct fc_lport *base_lport;
-
- if (!(qedf_is_vport(qedf)))
- return NULL;
-
- lport = qedf->lport;
- base_lport = shost_priv(vport_to_shost(lport->vport));
- return (struct qedf_ctx *)(lport_priv(base_lport));
-}
-
void qedf_capture_grc_dump(struct qedf_ctx *qedf)
{
struct qedf_ctx *base_qedf;
diff --git a/drivers/scsi/qedf/qedf_dbg.h b/drivers/scsi/qedf/qedf_dbg.h
index 7d173f48a81e..50083cae84c3 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 Cavium Inc.
+ * Copyright (c) 2016-2017 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 00a1d6405ebe..2b1ef3075e93 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 QLogic Corporation
+ * Copyright (c) 2016-2017 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 90627033bde6..eb07f1de8afa 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 Cavium Inc.
+ * Copyright (c) 2016-2017 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,7 +44,7 @@ static int qedf_initiate_els(struct qedf_rport *fcport, unsigned int op,
goto els_err;
}
- if (!(test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags))) {
+ if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) {
QEDF_ERR(&(qedf->dbg_ctx), "els 0x%x: fcport not ready\n", op);
rc = -EINVAL;
goto els_err;
@@ -225,7 +225,7 @@ int qedf_send_rrq(struct qedf_ioreq *aborted_io_req)
fcport = aborted_io_req->fcport;
/* Check that fcport is still offloaded */
- if (!(test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags))) {
+ if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) {
QEDF_ERR(NULL, "fcport is no longer offloaded.\n");
return -EINVAL;
}
@@ -550,7 +550,7 @@ static int qedf_send_srr(struct qedf_ioreq *orig_io_req, u32 offset, u8 r_ctl)
fcport = orig_io_req->fcport;
/* Check that fcport is still offloaded */
- if (!(test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags))) {
+ if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) {
QEDF_ERR(NULL, "fcport is no longer offloaded.\n");
return -EINVAL;
}
diff --git a/drivers/scsi/qedf/qedf_fip.c b/drivers/scsi/qedf/qedf_fip.c
index e10b91cc3c62..aefd24ca9604 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 Cavium Inc.
+ * Copyright (c) 2016-2017 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
@@ -125,8 +125,7 @@ void qedf_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
sub = fiph->fip_subcode;
if (!qedf->vlan_hw_insert) {
- vlan_hdr = (struct vlan_ethhdr *)skb_push(skb, sizeof(*vlan_hdr)
- - sizeof(*eth_hdr));
+ vlan_hdr = skb_push(skb, sizeof(*vlan_hdr) - sizeof(*eth_hdr));
memcpy(vlan_hdr, eth_hdr, 2 * ETH_ALEN);
vlan_hdr->h_vlan_proto = htons(ETH_P_8021Q);
vlan_hdr->h_vlan_encapsulated_proto = eth_hdr->h_proto;
@@ -156,10 +155,9 @@ void qedf_fip_recv(struct qedf_ctx *qedf, struct sk_buff *skb)
struct fip_wwn_desc *wp;
struct fip_vn_desc *vp;
size_t rlen, dlen;
- uint32_t cvl_port_id;
- __u8 cvl_mac[ETH_ALEN];
u16 op;
u8 sub;
+ bool do_reset = false;
eth_hdr = (struct ethhdr *)skb_mac_header(skb);
fiph = (struct fip_header *) ((void *)skb->data + 2 * ETH_ALEN + 2);
@@ -190,8 +188,6 @@ void qedf_fip_recv(struct qedf_ctx *qedf, struct sk_buff *skb)
return;
}
- cvl_port_id = 0;
- memset(cvl_mac, 0, ETH_ALEN);
/*
* We need to loop through the CVL descriptors to determine
* if we want to reset the fcoe link
@@ -205,7 +201,9 @@ void qedf_fip_recv(struct qedf_ctx *qedf, struct sk_buff *skb)
mp = (struct fip_mac_desc *)desc;
QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2,
"fd_mac=%pM\n", mp->fd_mac);
- ether_addr_copy(cvl_mac, mp->fd_mac);
+ if (ether_addr_equal(mp->fd_mac,
+ qedf->ctlr.sel_fcf->fcf_mac))
+ do_reset = true;
break;
case FIP_DT_NAME:
wp = (struct fip_wwn_desc *)desc;
@@ -217,7 +215,9 @@ void qedf_fip_recv(struct qedf_ctx *qedf, struct sk_buff *skb)
vp = (struct fip_vn_desc *)desc;
QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2,
"fd_fc_id=%x.\n", ntoh24(vp->fd_fc_id));
- cvl_port_id = ntoh24(vp->fd_fc_id);
+ if (ntoh24(vp->fd_fc_id) ==
+ qedf->lport->port_id)
+ do_reset = true;
break;
default:
/* Ignore anything else */
@@ -228,11 +228,8 @@ void qedf_fip_recv(struct qedf_ctx *qedf, struct sk_buff *skb)
}
QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2,
- "cvl_port_id=%06x cvl_mac=%pM.\n", cvl_port_id,
- cvl_mac);
- if (cvl_port_id == qedf->lport->port_id &&
- ether_addr_equal(cvl_mac,
- qedf->ctlr.sel_fcf->fcf_mac)) {
+ "do_reset=%d.\n", do_reset);
+ if (do_reset) {
fcoe_ctlr_link_down(&qedf->ctlr);
qedf_wait_for_upload(qedf);
fcoe_ctlr_link_up(&qedf->ctlr);
diff --git a/drivers/scsi/qedf/qedf_hsi.h b/drivers/scsi/qedf/qedf_hsi.h
index dfd65dec2874..7faef80c5f7a 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 Cavium Inc.
+ * Copyright (c) 2016-2017 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 1d7f90d0adc1..ded386036c27 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 Cavium Inc.
+ * Copyright (c) 2016-2017 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
@@ -1041,10 +1041,13 @@ static void qedf_parse_fcp_rsp(struct qedf_ioreq *io_req,
fcp_sns_len = SCSI_SENSE_BUFFERSIZE;
}
- memset(sc_cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
- if (fcp_sns_len)
- memcpy(sc_cmd->sense_buffer, sense_data,
- fcp_sns_len);
+ /* The sense buffer can be NULL for TMF commands */
+ if (sc_cmd->sense_buffer) {
+ memset(sc_cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
+ if (fcp_sns_len)
+ memcpy(sc_cmd->sense_buffer, sense_data,
+ fcp_sns_len);
+ }
}
static void qedf_unmap_sg_list(struct qedf_ctx *qedf, struct qedf_ioreq *io_req)
@@ -1476,8 +1479,8 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts)
{
struct fc_lport *lport;
struct qedf_rport *fcport = io_req->fcport;
- struct fc_rport_priv *rdata = fcport->rdata;
- struct qedf_ctx *qedf = fcport->qedf;
+ struct fc_rport_priv *rdata;
+ struct qedf_ctx *qedf;
u16 xid;
u32 r_a_tov = 0;
int rc = 0;
@@ -1485,15 +1488,18 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts)
struct fcoe_wqe *sqe;
u16 sqe_idx;
- r_a_tov = rdata->r_a_tov;
- lport = qedf->lport;
-
+ /* Sanity check qedf_rport before dereferencing any pointers */
if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) {
- QEDF_ERR(&(qedf->dbg_ctx), "tgt not offloaded\n");
+ QEDF_ERR(NULL, "tgt not offloaded\n");
rc = 1;
goto abts_err;
}
+ rdata = fcport->rdata;
+ r_a_tov = rdata->r_a_tov;
+ qedf = fcport->qedf;
+ lport = qedf->lport;
+
if (lport->state != LPORT_ST_READY || !(lport->link_up)) {
QEDF_ERR(&(qedf->dbg_ctx), "link is not ready\n");
rc = 1;
@@ -1729,6 +1735,13 @@ int qedf_initiate_cleanup(struct qedf_ioreq *io_req,
return SUCCESS;
}
+ /* Sanity check qedf_rport before dereferencing any pointers */
+ if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) {
+ QEDF_ERR(NULL, "tgt not offloaded\n");
+ rc = 1;
+ return SUCCESS;
+ }
+
qedf = fcport->qedf;
if (!qedf) {
QEDF_ERR(NULL, "qedf is NULL.\n");
@@ -1837,7 +1850,7 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd,
return FAILED;
}
- if (!(test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags))) {
+ if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) {
QEDF_ERR(&(qedf->dbg_ctx), "fcport not offloaded\n");
rc = FAILED;
return FAILED;
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
index a5c97342fd5d..b58bba4604e8 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 Cavium Inc.
+ * Copyright (c) 2016-2017 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
@@ -22,6 +22,7 @@
#include <linux/if_vlan.h>
#include <linux/cpu.h>
#include "qedf.h"
+#include <uapi/linux/pci_regs.h>
const struct qed_fcoe_ops *qed_ops;
@@ -94,7 +95,7 @@ module_param_named(dp_module, qedf_dp_module, uint, S_IRUGO);
MODULE_PARM_DESC(dp_module, " bit flags control for verbose printk passed "
"qed module during probe.");
-static uint qedf_dp_level;
+static uint qedf_dp_level = QED_LEVEL_NOTICE;
module_param_named(dp_level, qedf_dp_level, uint, S_IRUGO);
MODULE_PARM_DESC(dp_level, " printk verbosity control passed to qed module "
"during probe (0-3: 0 more verbose).");
@@ -441,7 +442,8 @@ static void qedf_link_update(void *dev, struct qed_link_output *link)
qedf_update_link_speed(qedf, link);
if (atomic_read(&qedf->dcbx) == QEDF_DCBX_DONE) {
- QEDF_ERR(&(qedf->dbg_ctx), "DCBx done.\n");
+ QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC,
+ "DCBx done.\n");
if (atomic_read(&qedf->link_down_tmo_valid) > 0)
queue_delayed_work(qedf->link_update_wq,
&qedf->link_recovery, 0);
@@ -627,6 +629,16 @@ static int qedf_eh_device_reset(struct scsi_cmnd *sc_cmd)
return qedf_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET);
}
+static int qedf_eh_bus_reset(struct scsi_cmnd *sc_cmd)
+{
+ QEDF_ERR(NULL, "BUS RESET Issued...\n");
+ /*
+ * Essentially a no-op but return SUCCESS to prevent
+ * unnecessary escalation to the host reset handler.
+ */
+ return SUCCESS;
+}
+
void qedf_wait_for_upload(struct qedf_ctx *qedf)
{
while (1) {
@@ -639,27 +651,17 @@ void qedf_wait_for_upload(struct qedf_ctx *qedf)
}
}
-/* Reset the host by gracefully logging out and then logging back in */
-static int qedf_eh_host_reset(struct scsi_cmnd *sc_cmd)
+/* Performs soft reset of qedf_ctx by simulating a link down/up */
+static void qedf_ctx_soft_reset(struct fc_lport *lport)
{
- struct fc_lport *lport;
struct qedf_ctx *qedf;
- lport = shost_priv(sc_cmd->device->host);
-
if (lport->vport) {
QEDF_ERR(NULL, "Cannot issue host reset on NPIV port.\n");
- return SUCCESS;
+ return;
}
- qedf = (struct qedf_ctx *)lport_priv(lport);
-
- if (atomic_read(&qedf->link_state) == QEDF_LINK_DOWN ||
- test_bit(QEDF_UNLOADING, &qedf->flags) ||
- test_bit(QEDF_DBG_STOP_IO, &qedf->flags))
- return FAILED;
-
- QEDF_ERR(&(qedf->dbg_ctx), "HOST RESET Issued...");
+ qedf = lport_priv(lport);
/* For host reset, essentially do a soft link up/down */
atomic_set(&qedf->link_state, QEDF_LINK_DOWN);
@@ -671,6 +673,24 @@ static int qedf_eh_host_reset(struct scsi_cmnd *sc_cmd)
qedf->vlan_id = 0;
queue_delayed_work(qedf->link_update_wq, &qedf->link_update,
0);
+}
+
+/* Reset the host by gracefully logging out and then logging back in */
+static int qedf_eh_host_reset(struct scsi_cmnd *sc_cmd)
+{
+ struct fc_lport *lport;
+ struct qedf_ctx *qedf;
+
+ lport = shost_priv(sc_cmd->device->host);
+ qedf = lport_priv(lport);
+
+ if (atomic_read(&qedf->link_state) == QEDF_LINK_DOWN ||
+ test_bit(QEDF_UNLOADING, &qedf->flags))
+ return FAILED;
+
+ QEDF_ERR(&(qedf->dbg_ctx), "HOST RESET Issued...");
+
+ qedf_ctx_soft_reset(lport);
return SUCCESS;
}
@@ -688,7 +708,7 @@ static struct scsi_host_template qedf_host_template = {
.module = THIS_MODULE,
.name = QEDF_MODULE_NAME,
.this_id = -1,
- .cmd_per_lun = 3,
+ .cmd_per_lun = 32,
.use_clustering = ENABLE_CLUSTERING,
.max_sectors = 0xffff,
.queuecommand = qedf_queuecommand,
@@ -696,11 +716,13 @@ static struct scsi_host_template qedf_host_template = {
.eh_abort_handler = qedf_eh_abort,
.eh_device_reset_handler = qedf_eh_device_reset, /* lun reset */
.eh_target_reset_handler = qedf_eh_target_reset, /* target reset */
+ .eh_bus_reset_handler = qedf_eh_bus_reset,
.eh_host_reset_handler = qedf_eh_host_reset,
.slave_configure = qedf_slave_configure,
.dma_boundary = QED_HW_DMA_BOUNDARY,
.sg_tablesize = QEDF_MAX_BDS_PER_CMD,
.can_queue = FCOE_PARAMS_NUM_TASKS,
+ .change_queue_depth = scsi_change_queue_depth,
};
static int qedf_get_paged_crc_eof(struct sk_buff *skb, int tlen)
@@ -874,7 +896,7 @@ static int qedf_xmit(struct fc_lport *lport, struct fc_frame *fp)
frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1];
cp = kmap_atomic(skb_frag_page(frag)) + frag->page_offset;
} else {
- cp = (struct fcoe_crc_eof *)skb_put(skb, tlen);
+ cp = skb_put(skb, tlen);
}
memset(cp, 0, sizeof(*cp));
@@ -950,25 +972,21 @@ static int qedf_alloc_sq(struct qedf_ctx *qedf, struct qedf_rport *fcport)
sizeof(void *);
fcport->sq_pbl_size = fcport->sq_pbl_size + QEDF_PAGE_SIZE;
- fcport->sq = dma_alloc_coherent(&qedf->pdev->dev, fcport->sq_mem_size,
- &fcport->sq_dma, GFP_KERNEL);
+ fcport->sq = dma_zalloc_coherent(&qedf->pdev->dev,
+ fcport->sq_mem_size, &fcport->sq_dma, GFP_KERNEL);
if (!fcport->sq) {
- QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate send "
- "queue.\n");
+ QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate send queue.\n");
rval = 1;
goto out;
}
- memset(fcport->sq, 0, fcport->sq_mem_size);
- fcport->sq_pbl = dma_alloc_coherent(&qedf->pdev->dev,
+ fcport->sq_pbl = dma_zalloc_coherent(&qedf->pdev->dev,
fcport->sq_pbl_size, &fcport->sq_pbl_dma, GFP_KERNEL);
if (!fcport->sq_pbl) {
- QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate send "
- "queue PBL.\n");
+ QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate send queue PBL.\n");
rval = 1;
goto out_free_sq;
}
- memset(fcport->sq_pbl, 0, fcport->sq_pbl_size);
/* Create PBL */
num_pages = fcport->sq_mem_size / QEDF_PAGE_SIZE;
@@ -1334,6 +1352,59 @@ static void qedf_fcoe_ctlr_setup(struct qedf_ctx *qedf)
ether_addr_copy(qedf->ctlr.ctl_src_addr, qedf->mac);
}
+static void qedf_setup_fdmi(struct qedf_ctx *qedf)
+{
+ struct fc_lport *lport = qedf->lport;
+ struct fc_host_attrs *fc_host = shost_to_fc_host(lport->host);
+ u8 buf[8];
+ int i, pos;
+
+ /*
+ * fdmi_enabled needs to be set for libfc to execute FDMI registration.
+ */
+ lport->fdmi_enabled = 1;
+
+ /*
+ * Setup the necessary fc_host attributes to that will be used to fill
+ * in the FDMI information.
+ */
+
+ /* Get the PCI-e Device Serial Number Capability */
+ pos = pci_find_ext_capability(qedf->pdev, PCI_EXT_CAP_ID_DSN);
+ if (pos) {
+ pos += 4;
+ for (i = 0; i < 8; i++)
+ pci_read_config_byte(qedf->pdev, pos + i, &buf[i]);
+
+ snprintf(fc_host->serial_number,
+ sizeof(fc_host->serial_number),
+ "%02X%02X%02X%02X%02X%02X%02X%02X",
+ buf[7], buf[6], buf[5], buf[4],
+ buf[3], buf[2], buf[1], buf[0]);
+ } else
+ snprintf(fc_host->serial_number,
+ sizeof(fc_host->serial_number), "Unknown");
+
+ snprintf(fc_host->manufacturer,
+ sizeof(fc_host->manufacturer), "%s", "Cavium Inc.");
+
+ snprintf(fc_host->model, sizeof(fc_host->model), "%s", "QL41000");
+
+ snprintf(fc_host->model_description, sizeof(fc_host->model_description),
+ "%s", "QLogic FastLinQ QL41000 Series 10/25/40/50GGbE Controller"
+ "(FCoE)");
+
+ snprintf(fc_host->hardware_version, sizeof(fc_host->hardware_version),
+ "Rev %d", qedf->pdev->revision);
+
+ snprintf(fc_host->driver_version, sizeof(fc_host->driver_version),
+ "%s", QEDF_VERSION);
+
+ snprintf(fc_host->firmware_version, sizeof(fc_host->firmware_version),
+ "%d.%d.%d.%d", FW_MAJOR_VERSION, FW_MINOR_VERSION,
+ FW_REVISION_VERSION, FW_ENGINEERING_VERSION);
+}
+
static int qedf_lport_setup(struct qedf_ctx *qedf)
{
struct fc_lport *lport = qedf->lport;
@@ -1377,6 +1448,8 @@ static int qedf_lport_setup(struct qedf_ctx *qedf)
snprintf(fc_host_symbolic_name(lport->host), 256,
"QLogic %s v%s", QEDF_MODULE_NAME, QEDF_VERSION);
+ qedf_setup_fdmi(qedf);
+
return 0;
}
@@ -1613,8 +1686,7 @@ static int qedf_fcoe_reset(struct Scsi_Host *shost)
{
struct fc_lport *lport = shost_priv(shost);
- fc_fabric_logoff(lport);
- fc_fabric_login(lport);
+ qedf_ctx_soft_reset(lport);
return 0;
}
@@ -1979,6 +2051,8 @@ static int qedf_setup_int(struct qedf_ctx *qedf)
* Learn interrupt configuration
*/
rc = qed_ops->common->set_fp_int(qedf->cdev, num_online_cpus());
+ if (rc <= 0)
+ return 0;
rc = qed_ops->common->get_fp_int(qedf->cdev, &qedf->int_info);
if (rc)
@@ -2011,6 +2085,8 @@ static void qedf_recv_frame(struct qedf_ctx *qedf,
u8 *dest_mac = NULL;
struct fcoe_hdr *hp;
struct qedf_rport *fcport;
+ struct fc_lport *vn_port;
+ u32 f_ctl;
lport = qedf->lport;
if (lport == NULL || lport->state == LPORT_ST_DISABLED) {
@@ -2047,6 +2123,10 @@ static void qedf_recv_frame(struct qedf_ctx *qedf,
fh = fc_frame_header_get(fp);
+ /*
+ * Invalid frame filters.
+ */
+
if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
fh->fh_type == FC_TYPE_FCP) {
/* Drop FCP data. We dont this in L2 path */
@@ -2072,6 +2152,45 @@ static void qedf_recv_frame(struct qedf_ctx *qedf,
return;
}
+ 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);
+ return;
+ }
+
+ if (qedf->ctlr.state) {
+ if (!ether_addr_equal(mac, qedf->ctlr.dest_addr)) {
+ QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2,
+ "Wrong source address: mac:%pM dest_addr:%pM.\n",
+ mac, qedf->ctlr.dest_addr);
+ kfree_skb(skb);
+ return;
+ }
+ }
+
+ vn_port = fc_vport_id_lookup(lport, ntoh24(fh->fh_d_id));
+
+ /*
+ * If the destination ID from the frame header does not match what we
+ * have on record for lport and the search for a NPIV port came up
+ * empty then this is not addressed to our port so simply drop it.
+ */
+ if (lport->port_id != ntoh24(fh->fh_d_id) && !vn_port) {
+ QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2,
+ "Dropping frame due to destination mismatch: lport->port_id=%x fh->d_id=%x.\n",
+ lport->port_id, ntoh24(fh->fh_d_id));
+ kfree_skb(skb);
+ return;
+ }
+
+ f_ctl = ntoh24(fh->fh_f_ctl);
+ if ((fh->fh_type == FC_TYPE_BLS) && (f_ctl & FC_FC_SEQ_CTX) &&
+ (f_ctl & FC_FC_EX_CTX)) {
+ /* Drop incoming ABTS response that has both SEQ/EX CTX set */
+ kfree_skb(skb);
+ return;
+ }
+
/*
* If a connection is uploading, drop incoming FCoE frames as there
* is a small window where we could try to return a frame while libfc
@@ -2117,7 +2236,7 @@ static void qedf_ll2_process_skb(struct work_struct *work)
/* Undo VLAN encapsulation */
if (eh->h_proto == htons(ETH_P_8021Q)) {
memmove((u8 *)eh + VLAN_HLEN, eh, ETH_ALEN * 2);
- eh = (struct ethhdr *)skb_pull(skb, VLAN_HLEN);
+ eh = skb_pull(skb, VLAN_HLEN);
skb_reset_mac_header(skb);
}
@@ -2474,14 +2593,12 @@ static int qedf_alloc_bdq(struct qedf_ctx *qedf)
}
/* Allocate list of PBL pages */
- qedf->bdq_pbl_list = dma_alloc_coherent(&qedf->pdev->dev,
+ qedf->bdq_pbl_list = dma_zalloc_coherent(&qedf->pdev->dev,
QEDF_PAGE_SIZE, &qedf->bdq_pbl_list_dma, GFP_KERNEL);
if (!qedf->bdq_pbl_list) {
- QEDF_ERR(&(qedf->dbg_ctx), "Could not allocate list of PBL "
- "pages.\n");
+ QEDF_ERR(&(qedf->dbg_ctx), "Could not allocate list of PBL pages.\n");
return -ENOMEM;
}
- memset(qedf->bdq_pbl_list, 0, QEDF_PAGE_SIZE);
/*
* Now populate PBL list with pages that contain pointers to the
@@ -2548,8 +2665,9 @@ static int qedf_alloc_global_queues(struct qedf_ctx *qedf)
qedf->global_queues[i] = kzalloc(sizeof(struct global_queue),
GFP_KERNEL);
if (!qedf->global_queues[i]) {
- QEDF_WARN(&(qedf->dbg_ctx), "Unable to allocation "
+ QEDF_WARN(&(qedf->dbg_ctx), "Unable to allocate "
"global queue %d.\n", i);
+ status = -ENOMEM;
goto mem_alloc_failure;
}
@@ -2565,32 +2683,26 @@ static int qedf_alloc_global_queues(struct qedf_ctx *qedf)
ALIGN(qedf->global_queues[i]->cq_pbl_size, QEDF_PAGE_SIZE);
qedf->global_queues[i]->cq =
- dma_alloc_coherent(&qedf->pdev->dev,
+ dma_zalloc_coherent(&qedf->pdev->dev,
qedf->global_queues[i]->cq_mem_size,
&qedf->global_queues[i]->cq_dma, GFP_KERNEL);
if (!qedf->global_queues[i]->cq) {
- QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate "
- "cq.\n");
+ QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate cq.\n");
status = -ENOMEM;
goto mem_alloc_failure;
}
- memset(qedf->global_queues[i]->cq, 0,
- qedf->global_queues[i]->cq_mem_size);
qedf->global_queues[i]->cq_pbl =
- dma_alloc_coherent(&qedf->pdev->dev,
+ dma_zalloc_coherent(&qedf->pdev->dev,
qedf->global_queues[i]->cq_pbl_size,
&qedf->global_queues[i]->cq_pbl_dma, GFP_KERNEL);
if (!qedf->global_queues[i]->cq_pbl) {
- QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate "
- "cq PBL.\n");
+ QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate cq PBL.\n");
status = -ENOMEM;
goto mem_alloc_failure;
}
- memset(qedf->global_queues[i]->cq_pbl, 0,
- qedf->global_queues[i]->cq_pbl_size);
/* Create PBL */
num_pages = qedf->global_queues[i]->cq_mem_size /
@@ -2683,8 +2795,7 @@ static int qedf_set_fcoe_pf_param(struct qedf_ctx *qedf)
cq_mem_size = ALIGN(cq_mem_size, QEDF_PAGE_SIZE);
cq_num_entries = cq_mem_size / sizeof(struct fcoe_cqe);
- memset(&(qedf->pf_params), 0,
- sizeof(qedf->pf_params));
+ memset(&(qedf->pf_params), 0, sizeof(qedf->pf_params));
/* Setup the value for fcoe PF */
qedf->pf_params.fcoe_pf_params.num_cons = QEDF_MAX_SESSIONS;
@@ -2954,7 +3065,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
"WWPN=%016llx.\n", qedf->wwnn, qedf->wwpn);
sprintf(host_buf, "host_%d", host->host_no);
- qed_ops->common->set_id(qedf->cdev, host_buf, QEDF_VERSION);
+ qed_ops->common->set_name(qedf->cdev, host_buf);
/* Set xid max values */
diff --git a/drivers/scsi/qedf/qedf_version.h b/drivers/scsi/qedf/qedf_version.h
index 4ae5f537a440..6fa442061c32 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 Cavium Inc.
+ * Copyright (c) 2016-2017 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.10.7.0"
+#define QEDF_VERSION "8.18.22.0"
#define QEDF_DRIVER_MAJOR_VER 8
-#define QEDF_DRIVER_MINOR_VER 10
-#define QEDF_DRIVER_REV_VER 7
+#define QEDF_DRIVER_MINOR_VER 18
+#define QEDF_DRIVER_REV_VER 22
#define QEDF_DRIVER_ENG_VER 0