diff options
Diffstat (limited to 'drivers/scsi/qedf')
-rw-r--r-- | drivers/scsi/qedf/qedf.h | 2 | ||||
-rw-r--r-- | drivers/scsi/qedf/qedf_fip.c | 35 | ||||
-rw-r--r-- | drivers/scsi/qedf/qedf_main.c | 113 | ||||
-rw-r--r-- | drivers/scsi/qedf/qedf_version.h | 6 |
4 files changed, 92 insertions, 64 deletions
diff --git a/drivers/scsi/qedf/qedf.h b/drivers/scsi/qedf/qedf.h index 351f06dfc5a0..9bf7b227e69a 100644 --- a/drivers/scsi/qedf/qedf.h +++ b/drivers/scsi/qedf/qedf.h @@ -300,7 +300,6 @@ struct qedf_ctx { #define QEDF_FALLBACK_VLAN 1002 #define QEDF_DEFAULT_PRIO 3 int vlan_id; - uint vlan_hw_insert:1; struct qed_dev *cdev; struct qed_dev_fcoe_info dev_info; struct qed_int_info int_info; @@ -443,7 +442,6 @@ extern void qedf_cmd_mgr_free(struct qedf_cmd_mgr *cmgr); extern int qedf_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc_cmd); extern void qedf_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb); -extern void qedf_update_src_mac(struct fc_lport *lport, u8 *addr); extern u8 *qedf_get_src_mac(struct fc_lport *lport); extern void qedf_fip_recv(struct qedf_ctx *qedf, struct sk_buff *skb); extern void qedf_fcoe_send_vlan_req(struct qedf_ctx *qedf); diff --git a/drivers/scsi/qedf/qedf_fip.c b/drivers/scsi/qedf/qedf_fip.c index aefd24ca9604..773558fc0697 100644 --- a/drivers/scsi/qedf/qedf_fip.c +++ b/drivers/scsi/qedf/qedf_fip.c @@ -108,7 +108,6 @@ void qedf_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb) { struct qedf_ctx *qedf = container_of(fip, struct qedf_ctx, ctlr); struct ethhdr *eth_hdr; - struct vlan_ethhdr *vlan_hdr; struct fip_header *fiph; u16 op, vlan_tci = 0; u8 sub; @@ -124,16 +123,14 @@ void qedf_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb) op = ntohs(fiph->fip_op); sub = fiph->fip_subcode; - if (!qedf->vlan_hw_insert) { - 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; - vlan_hdr->h_vlan_TCI = vlan_tci = htons(qedf->vlan_id); - } + /* + * Add VLAN tag to non-offload FIP frame based on current stored VLAN + * for FIP/FCoE traffic. + */ + __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), qedf->vlan_id); - /* Update eth_hdr since we added a VLAN tag */ - eth_hdr = (struct ethhdr *)skb_mac_header(skb); + /* Get VLAN ID from skb for printing purposes */ + __vlan_hwaccel_get_tag(skb, &vlan_tci); 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, @@ -174,7 +171,6 @@ void qedf_fip_recv(struct qedf_ctx *qedf, struct sk_buff *skb) /* Handle FIP VLAN resp in the driver */ if (op == FIP_OP_VLAN && sub == FIP_SC_VL_NOTE) { qedf_fcoe_process_vlan_resp(qedf, skb); - qedf->vlan_hw_insert = 0; kfree_skb(skb); } else if (op == FIP_OP_CTRL && sub == FIP_SC_CLR_VLINK) { QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, "Clear virtual " @@ -242,26 +238,9 @@ void qedf_fip_recv(struct qedf_ctx *qedf, struct sk_buff *skb) } } -void qedf_update_src_mac(struct fc_lport *lport, u8 *addr) -{ - struct qedf_ctx *qedf = lport_priv(lport); - - QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, - "Setting data_src_addr=%pM.\n", addr); - ether_addr_copy(qedf->data_src_addr, addr); -} - u8 *qedf_get_src_mac(struct fc_lport *lport) { - u8 mac[ETH_ALEN]; - u8 port_id[3]; struct qedf_ctx *qedf = lport_priv(lport); - /* We need to use the lport port_id to create the data_src_addr */ - if (is_zero_ether_addr(qedf->data_src_addr)) { - hton24(port_id, lport->port_id); - fc_fcoe_set_mac(mac, port_id); - qedf->ctlr.update_mac(lport, mac); - } return qedf->data_src_addr; } diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index 1d13c9ca517d..7c0064500cc5 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -18,6 +18,7 @@ #include <linux/kthread.h> #include <scsi/libfc.h> #include <scsi/scsi_host.h> +#include <scsi/fc_frame.h> #include <linux/if_ether.h> #include <linux/if_vlan.h> #include <linux/cpu.h> @@ -42,7 +43,7 @@ MODULE_PARM_DESC(dev_loss_tmo, " dev_loss_tmo setting for attached " uint qedf_debug = QEDF_LOG_INFO; module_param_named(debug, qedf_debug, uint, S_IRUGO); -MODULE_PARM_DESC(qedf_debug, " Debug mask. Pass '1' to enable default debugging" +MODULE_PARM_DESC(debug, " Debug mask. Pass '1' to enable default debugging" " mask"); static uint qedf_fipvlan_retries = 30; @@ -163,7 +164,7 @@ static void qedf_handle_link_update(struct work_struct *work) QEDF_WARN(&(qedf->dbg_ctx), "Did not receive FIP VLAN " "response, falling back to default VLAN %d.\n", qedf_fallback_vlan); - qedf_set_vlan_id(qedf, QEDF_FALLBACK_VLAN); + qedf_set_vlan_id(qedf, qedf_fallback_vlan); /* * Zero out data_src_addr so we'll update it with the new @@ -187,6 +188,50 @@ static void qedf_handle_link_update(struct work_struct *work) } } +#define QEDF_FCOE_MAC_METHOD_GRANGED_MAC 1 +#define QEDF_FCOE_MAC_METHOD_FCF_MAP 2 +#define QEDF_FCOE_MAC_METHOD_FCOE_SET_MAC 3 +static void qedf_set_data_src_addr(struct qedf_ctx *qedf, struct fc_frame *fp) +{ + u8 *granted_mac; + struct fc_frame_header *fh = fc_frame_header_get(fp); + u8 fc_map[3]; + int method = 0; + + /* Get granted MAC address from FIP FLOGI payload */ + granted_mac = fr_cb(fp)->granted_mac; + + /* + * We set the source MAC for FCoE traffic based on the Granted MAC + * address from the switch. + * + * If granted_mac is non-zero, we used that. + * If the granted_mac is zeroed out, created the FCoE MAC based on + * the sel_fcf->fc_map and the d_id fo the FLOGI frame. + * If sel_fcf->fc_map is 0 then we use the default FCF-MAC plus the + * d_id of the FLOGI frame. + */ + if (!is_zero_ether_addr(granted_mac)) { + ether_addr_copy(qedf->data_src_addr, granted_mac); + method = QEDF_FCOE_MAC_METHOD_GRANGED_MAC; + } else if (qedf->ctlr.sel_fcf->fc_map != 0) { + hton24(fc_map, qedf->ctlr.sel_fcf->fc_map); + qedf->data_src_addr[0] = fc_map[0]; + qedf->data_src_addr[1] = fc_map[1]; + qedf->data_src_addr[2] = fc_map[2]; + qedf->data_src_addr[3] = fh->fh_d_id[0]; + qedf->data_src_addr[4] = fh->fh_d_id[1]; + qedf->data_src_addr[5] = fh->fh_d_id[2]; + method = QEDF_FCOE_MAC_METHOD_FCF_MAP; + } else { + fc_fcoe_set_mac(qedf->data_src_addr, fh->fh_d_id); + method = QEDF_FCOE_MAC_METHOD_FCOE_SET_MAC; + } + + QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, + "QEDF data_src_mac=%pM method=%d.\n", qedf->data_src_addr, method); +} + static void qedf_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg) { @@ -212,6 +257,10 @@ static void qedf_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, /* Log stats for FLOGI reject */ if (fc_frame_payload_op(fp) == ELS_LS_RJT) qedf->flogi_failed++; + else if (fc_frame_payload_op(fp) == ELS_LS_ACC) { + /* Set the source MAC we will use for FCoE traffic */ + qedf_set_data_src_addr(qedf, fp); + } /* Complete flogi_compl so we can proceed to sending ADISCs */ complete(&qedf->flogi_compl); @@ -312,8 +361,9 @@ static void qedf_link_recovery(struct work_struct *work) /* Since the link when down and up to verify which vlan we're on */ qedf->fipvlan_retries = qedf_fipvlan_retries; rc = qedf_initiate_fipvlan_req(qedf); + /* If getting the VLAN fails, set the VLAN to the fallback one */ if (!rc) - return; + qedf_set_vlan_id(qedf, qedf_fallback_vlan); /* * We need to wait for an FCF to be selected due to the @@ -629,16 +679,6 @@ 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) { @@ -716,7 +756,6 @@ 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, @@ -915,6 +954,10 @@ static int qedf_xmit(struct fc_lport *lport, struct fc_frame *fp) skb->mac_len = elen; skb->protocol = htons(ETH_P_FCOE); + /* + * Add VLAN tag to non-offload FCoE frame based on current stored VLAN + * for FIP/FCoE traffic. + */ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), qedf->vlan_id); /* fill up mac and fcoe headers */ @@ -927,7 +970,7 @@ static int qedf_xmit(struct fc_lport *lport, struct fc_frame *fp) ether_addr_copy(eh->h_dest, qedf->ctlr.dest_addr); /* Set the source MAC address */ - fc_fcoe_set_mac(eh->h_source, fh->fh_s_id); + ether_addr_copy(eh->h_source, qedf->data_src_addr); hp = (struct fcoe_hdr *)(eh + 1); memset(hp, 0, sizeof(*hp)); @@ -1025,7 +1068,6 @@ static int qedf_offload_connection(struct qedf_ctx *qedf, { struct qed_fcoe_params_offload conn_info; u32 port_id; - u8 lport_src_id[3]; int rval; uint16_t total_sqe = (fcport->sq_mem_size / sizeof(struct fcoe_wqe)); @@ -1054,11 +1096,7 @@ static int qedf_offload_connection(struct qedf_ctx *qedf, (dma_addr_t)(*(u64 *)(fcport->sq_pbl + 8)); /* Need to use our FCoE MAC for the offload session */ - port_id = fc_host_port_id(qedf->lport->host); - lport_src_id[2] = (port_id & 0x000000FF); - lport_src_id[1] = (port_id & 0x0000FF00) >> 8; - lport_src_id[0] = (port_id & 0x00FF0000) >> 16; - fc_fcoe_set_mac(conn_info.src_mac, lport_src_id); + ether_addr_copy(conn_info.src_mac, qedf->data_src_addr); ether_addr_copy(conn_info.dst_mac, qedf->ctlr.dest_addr); @@ -1347,7 +1385,6 @@ static void qedf_fcoe_ctlr_setup(struct qedf_ctx *qedf) fcoe_ctlr_init(&qedf->ctlr, FIP_ST_AUTO); qedf->ctlr.send = qedf_fip_send; - qedf->ctlr.update_mac = qedf_update_src_mac; qedf->ctlr.get_src_addr = qedf_get_src_mac; ether_addr_copy(qedf->ctlr.ctl_src_addr, qedf->mac); } @@ -2939,7 +2976,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode) sprintf(host_buf, "qedf_%u_link", qedf->lport->host->host_no); - qedf->link_update_wq = create_singlethread_workqueue(host_buf); + 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); @@ -3056,9 +3093,24 @@ static int __qedf_probe(struct pci_dev *pdev, int mode) QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, "MAC address is %pM.\n", qedf->mac); - /* Set the WWNN and WWPN based on the MAC address */ - qedf->wwnn = fcoe_wwn_from_mac(qedf->mac, 1, 0); - qedf->wwpn = fcoe_wwn_from_mac(qedf->mac, 2, 0); + /* + * Set the WWNN and WWPN in the following way: + * + * If the info we get from qed is non-zero then use that to set the + * WWPN and WWNN. Otherwise fall back to use fcoe_wwn_from_mac() based + * on the MAC address. + */ + if (qedf->dev_info.wwnn != 0 && qedf->dev_info.wwpn != 0) { + QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, + "Setting WWPN and WWNN from qed dev_info.\n"); + qedf->wwnn = qedf->dev_info.wwnn; + qedf->wwpn = qedf->dev_info.wwpn; + } else { + QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, + "Setting WWPN and WWNN using fcoe_wwn_from_mac().\n"); + qedf->wwnn = fcoe_wwn_from_mac(qedf->mac, 1, 0); + qedf->wwpn = fcoe_wwn_from_mac(qedf->mac, 2, 0); + } QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, "WWNN=%016llx " "WWPN=%016llx.\n", qedf->wwnn, qedf->wwpn); @@ -3094,7 +3146,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode) /* Start LL2 processing thread */ snprintf(host_buf, 20, "qedf_%d_ll2", host->host_no); qedf->ll2_recv_wq = - create_singlethread_workqueue(host_buf); + create_workqueue(host_buf); if (!qedf->ll2_recv_wq) { QEDF_ERR(&(qedf->dbg_ctx), "Failed to LL2 workqueue.\n"); goto err7; @@ -3114,8 +3166,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode) } set_bit(QEDF_LL2_STARTED, &qedf->flags); - /* hw will be insterting vlan tag*/ - qedf->vlan_hw_insert = 1; + /* Set initial FIP/FCoE VLAN to NULL */ qedf->vlan_id = 0; /* @@ -3137,7 +3188,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode) sprintf(host_buf, "qedf_%u_timer", qedf->lport->host->host_no); qedf->timer_work_queue = - create_singlethread_workqueue(host_buf); + create_workqueue(host_buf); if (!qedf->timer_work_queue) { QEDF_ERR(&(qedf->dbg_ctx), "Failed to start timer " "workqueue.\n"); @@ -3148,7 +3199,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode) if (mode != QEDF_MODE_RECOVERY) { sprintf(host_buf, "qedf_%u_dpc", qedf->lport->host->host_no); - qedf->dpc_wq = create_singlethread_workqueue(host_buf); + qedf->dpc_wq = create_workqueue(host_buf); } /* diff --git a/drivers/scsi/qedf/qedf_version.h b/drivers/scsi/qedf/qedf_version.h index 6fa442061c32..397b3b8ee51a 100644 --- a/drivers/scsi/qedf/qedf_version.h +++ b/drivers/scsi/qedf/qedf_version.h @@ -7,9 +7,9 @@ * this source tree. */ -#define QEDF_VERSION "8.18.22.0" +#define QEDF_VERSION "8.20.5.0" #define QEDF_DRIVER_MAJOR_VER 8 -#define QEDF_DRIVER_MINOR_VER 18 -#define QEDF_DRIVER_REV_VER 22 +#define QEDF_DRIVER_MINOR_VER 20 +#define QEDF_DRIVER_REV_VER 5 #define QEDF_DRIVER_ENG_VER 0 |