mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-23 07:23:12 +02:00
Merge patch series "Introduce support for Fabric Discovery and Login Services"
Karan Tilak Kumar <kartilak@cisco.com> says: Hi Martin, reviewers, This cover letter describes the feature: add support for Fabric Discovery and Login Services (FDLS) to fnic driver. This functionality is needed to support port channel RSCN (PC-RSCN) handling and serves as a base to create FC-NVME initiators (planned later), and eCPU handling (planned later). It is used to discover the fabric and target ports associated with the fabric. It will then login to the target ports that are zoned to it. The driver uses the tport structure presented by FDLS. Port channel RSCN is a Cisco vendor specific RSCN event. It is applicable only to Cisco UCS fabrics. In cases where the eCPU in the UCS VIC (Unified Computing Services Virtual Interface Card) hangs, a fabric log out is sent to the fabric. Upon successful log out from the fabric, the IO path is failed over to a new path. Generally from a feature perspective, the code is divided into adding support for this functionality initially. Then, code has been added to modify the IO path and interfaces. Finally, support for port channel RSCN handling has been added. Here are the headers of some of the salient patches: o add headers and definitions for FDLS o add support for fabric based solicited requests and responses o add support for target based solicited requests and responses o add support for unsolicited requests and responses o add support for FDMI o add support for FIP o add functionality in fnic to support FDLS o modify IO path to use FDLS and tport o modify fnic interfaces to use FDLS o add support to handle port channel RSCN Even though the patches have been made into a series, some patches are heavier than others. But, every effort has been made to keep the purpose of each patch as a single-purpose, and to compile cleanly. All the individual patches compile cleanly. The compiler used is GCC 13.3. Some function calls have been coded as placeholders with appropriate comments to avoid compiler warnings. This patchset has been tested as a whole. Therefore, the tested-by fields have been added only to one patch in the set. I've refrained from adding tested-by to most of the patches, so as to not mislead the reviewer/reader. A brief note on the unit tests: o. Perform zone in zone out testing in a loop: remove a target port from the zone, add it to the zone in a loop. 1000+ iterations of this test have been successful. o. Configure multipathing, and run link flaps on single link. IOs drop briefly, but pick up as expected. o. Configure multipathing, and run link flaps on two links, with a 30 second delay in between. IOs drop briefly, but pick up as expected. o. Module load/unload test. o. Repeat the above tests with 1 queue and 64 queues. All tests were successful. Please consider this patch series for the next merge window. Link: https://lore.kernel.org/r/20241212020312.4786-1-kartilak@cisco.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
commit
7d6f88e76e
|
@ -2,11 +2,13 @@
|
|||
obj-$(CONFIG_FCOE_FNIC) += fnic.o
|
||||
|
||||
fnic-y := \
|
||||
fip.o\
|
||||
fnic_attrs.o \
|
||||
fnic_isr.o \
|
||||
fnic_main.o \
|
||||
fnic_res.o \
|
||||
fnic_fcs.o \
|
||||
fdls_disc.o \
|
||||
fnic_scsi.o \
|
||||
fnic_trace.o \
|
||||
fnic_debugfs.o \
|
||||
|
@ -15,4 +17,5 @@ fnic-y := \
|
|||
vnic_intr.o \
|
||||
vnic_rq.o \
|
||||
vnic_wq_copy.o \
|
||||
vnic_wq.o
|
||||
vnic_wq.o \
|
||||
fnic_pci_subsys_devid.o
|
||||
|
|
4997
drivers/scsi/fnic/fdls_disc.c
Normal file
4997
drivers/scsi/fnic/fdls_disc.c
Normal file
File diff suppressed because it is too large
Load Diff
253
drivers/scsi/fnic/fdls_fc.h
Normal file
253
drivers/scsi/fnic/fdls_fc.h
Normal file
|
@ -0,0 +1,253 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright 2008 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _FDLS_FC_H_
|
||||
#define _FDLS_FC_H_
|
||||
|
||||
/* This file contains the declarations for FC fabric services
|
||||
* and target discovery
|
||||
*
|
||||
* Request and Response for
|
||||
* 1. FLOGI
|
||||
* 2. PLOGI to Fabric Controller
|
||||
* 3. GPN_ID, GPN_FT
|
||||
* 4. RSCN
|
||||
* 5. PLOGI to Target
|
||||
* 6. PRLI to Target
|
||||
*/
|
||||
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/fc/fc_els.h>
|
||||
#include <uapi/scsi/fc/fc_fs.h>
|
||||
#include <uapi/scsi/fc/fc_ns.h>
|
||||
#include <uapi/scsi/fc/fc_gs.h>
|
||||
#include <uapi/linux/if_ether.h>
|
||||
#include <scsi/fc/fc_ms.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <scsi/fc/fc_encaps.h>
|
||||
#include <scsi/fc/fc_fcoe.h>
|
||||
|
||||
#define FDLS_MIN_FRAMES (32)
|
||||
#define FDLS_MIN_FRAME_ELEM (4)
|
||||
#define FNIC_FCP_SP_RD_XRDY_DIS 0x00000002
|
||||
#define FNIC_FCP_SP_TARGET 0x00000010
|
||||
#define FNIC_FCP_SP_INITIATOR 0x00000020
|
||||
#define FNIC_FCP_SP_CONF_CMPL 0x00000080
|
||||
#define FNIC_FCP_SP_RETRY 0x00000100
|
||||
|
||||
#define FNIC_FC_CONCUR_SEQS (0xFF)
|
||||
#define FNIC_FC_RO_INFO (0x1F)
|
||||
|
||||
/* Little Endian */
|
||||
#define FNIC_UNASSIGNED_OXID (0xffff)
|
||||
#define FNIC_UNASSIGNED_RXID (0xffff)
|
||||
#define FNIC_ELS_REQ_FCTL (0x000029)
|
||||
#define FNIC_ELS_REP_FCTL (0x000099)
|
||||
|
||||
#define FNIC_FCP_RSP_FCTL (0x000099)
|
||||
#define FNIC_REQ_ABTS_FCTL (0x000009)
|
||||
|
||||
#define FNIC_FC_PH_VER_HI (0x20)
|
||||
#define FNIC_FC_PH_VER_LO (0x20)
|
||||
#define FNIC_FC_PH_VER (0x2020)
|
||||
#define FNIC_FC_B2B_CREDIT (0x0A)
|
||||
#define FNIC_FC_B2B_RDF_SZ (0x0800)
|
||||
|
||||
#define FNIC_LOGI_RDF_SIZE(_logi) ((_logi).fl_csp.sp_bb_data)
|
||||
#define FNIC_LOGI_R_A_TOV(_logi) ((_logi).fl_csp.sp_r_a_tov)
|
||||
#define FNIC_LOGI_E_D_TOV(_logi) ((_logi).fl_csp.sp_e_d_tov)
|
||||
#define FNIC_LOGI_FEATURES(_logi) (be16_to_cpu((_logi).fl_csp.sp_features))
|
||||
#define FNIC_LOGI_PORT_NAME(_logi) ((_logi).fl_wwpn)
|
||||
#define FNIC_LOGI_NODE_NAME(_logi) ((_logi).fl_wwnn)
|
||||
|
||||
#define FNIC_LOGI_SET_RDF_SIZE(_logi, _rdf_size) \
|
||||
(FNIC_LOGI_RDF_SIZE(_logi) = cpu_to_be16(_rdf_size))
|
||||
#define FNIC_LOGI_SET_E_D_TOV(_logi, _e_d_tov) \
|
||||
(FNIC_LOGI_E_D_TOV(_logi) = cpu_to_be32(_e_d_tov))
|
||||
#define FNIC_LOGI_SET_R_A_TOV(_logi, _r_a_tov) \
|
||||
(FNIC_LOGI_R_A_TOV(_logi) = cpu_to_be32(_r_a_tov))
|
||||
|
||||
#define FNIC_STD_SET_S_ID(_fchdr, _sid) memcpy((_fchdr).fh_s_id, _sid, 3)
|
||||
#define FNIC_STD_SET_D_ID(_fchdr, _did) memcpy((_fchdr).fh_d_id, _did, 3)
|
||||
#define FNIC_STD_SET_OX_ID(_fchdr, _oxid) ((_fchdr).fh_ox_id = cpu_to_be16(_oxid))
|
||||
#define FNIC_STD_SET_RX_ID(_fchdr, _rxid) ((_fchdr).fh_rx_id = cpu_to_be16(_rxid))
|
||||
|
||||
#define FNIC_STD_SET_R_CTL(_fchdr, _rctl) ((_fchdr).fh_r_ctl = _rctl)
|
||||
#define FNIC_STD_SET_TYPE(_fchdr, _type) ((_fchdr).fh_type = _type)
|
||||
#define FNIC_STD_SET_F_CTL(_fchdr, _fctl) \
|
||||
put_unaligned_be24(_fctl, &((_fchdr).fh_f_ctl))
|
||||
|
||||
#define FNIC_STD_SET_NPORT_NAME(_ptr, _wwpn) put_unaligned_be64(_wwpn, _ptr)
|
||||
#define FNIC_STD_SET_NODE_NAME(_ptr, _wwnn) put_unaligned_be64(_wwnn, _ptr)
|
||||
#define FNIC_STD_SET_PORT_ID(__req, __portid) \
|
||||
memcpy(__req.fr_fid.fp_fid, __portid, 3)
|
||||
#define FNIC_STD_SET_PORT_NAME(_req, _pName) \
|
||||
(put_unaligned_be64(_pName, &_req.fr_wwn))
|
||||
|
||||
#define FNIC_STD_GET_OX_ID(_fchdr) (be16_to_cpu((_fchdr)->fh_ox_id))
|
||||
#define FNIC_STD_GET_RX_ID(_fchdr) (be16_to_cpu((_fchdr)->fh_rx_id))
|
||||
#define FNIC_STD_GET_S_ID(_fchdr) ((_fchdr)->fh_s_id)
|
||||
#define FNIC_STD_GET_D_ID(_fchdr) ((_fchdr)->fh_d_id)
|
||||
#define FNIC_STD_GET_TYPE(_fchdr) ((_fchdr)->fh_type)
|
||||
#define FNIC_STD_GET_F_CTL(_fchdr) ((_fchdr)->fh_f_ctl)
|
||||
#define FNIC_STD_GET_R_CTL(_fchdr) ((_fchdr)->fh_r_ctl)
|
||||
|
||||
#define FNIC_STD_GET_FC_CT_CMD(__fcct_hdr) (be16_to_cpu(__fcct_hdr->ct_cmd))
|
||||
|
||||
#define FNIC_FCOE_MAX_FRAME_SZ (2048)
|
||||
#define FNIC_FCOE_MIN_FRAME_SZ (280)
|
||||
#define FNIC_FC_MAX_PAYLOAD_LEN (2048)
|
||||
#define FNIC_MIN_DATA_FIELD_SIZE (256)
|
||||
|
||||
#define FNIC_FC_EDTOV_NSEC (0x400)
|
||||
#define FNIC_NSEC_TO_MSEC (0x1000000)
|
||||
#define FCP_PRLI_FUNC_TARGET (0x0010)
|
||||
|
||||
#define FNIC_FC_R_CTL_SOLICITED_DATA (0x21)
|
||||
#define FNIC_FC_F_CTL_LAST_END_SEQ (0x98)
|
||||
#define FNIC_FC_F_CTL_LAST_END_SEQ_INT (0x99)
|
||||
#define FNIC_FC_F_CTL_FIRST_LAST_SEQINIT (0x29)
|
||||
#define FNIC_FC_R_CTL_FC4_SCTL (0x03)
|
||||
#define FNIC_FC_CS_CTL (0x00)
|
||||
|
||||
#define FNIC_FC_FRAME_UNSOLICITED(_fchdr) \
|
||||
(_fchdr->fh_r_ctl == FC_RCTL_ELS_REQ)
|
||||
#define FNIC_FC_FRAME_SOLICITED_DATA(_fchdr) \
|
||||
(_fchdr->fh_r_ctl == FNIC_FC_R_CTL_SOLICITED_DATA)
|
||||
#define FNIC_FC_FRAME_SOLICITED_CTRL_REPLY(_fchdr) \
|
||||
(_fchdr->fh_r_ctl == FC_RCTL_ELS_REP)
|
||||
#define FNIC_FC_FRAME_FCTL_LAST_END_SEQ(_fchdr) \
|
||||
(_fchdr->fh_f_ctl[0] == FNIC_FC_F_CTL_LAST_END_SEQ)
|
||||
#define FNIC_FC_FRAME_FCTL_LAST_END_SEQ_INT(_fchdr) \
|
||||
(_fchdr->fh_f_ctl[0] == FNIC_FC_F_CTL_LAST_END_SEQ_INT)
|
||||
#define FNIC_FC_FRAME_FCTL_FIRST_LAST_SEQINIT(_fchdr) \
|
||||
(_fchdr->fh_f_ctl[0] == FNIC_FC_F_CTL_FIRST_LAST_SEQINIT)
|
||||
#define FNIC_FC_FRAME_FC4_SCTL(_fchdr) \
|
||||
(_fchdr->fh_r_ctl == FNIC_FC_R_CTL_FC4_SCTL)
|
||||
#define FNIC_FC_FRAME_TYPE_BLS(_fchdr) (_fchdr->fh_type == FC_TYPE_BLS)
|
||||
#define FNIC_FC_FRAME_TYPE_ELS(_fchdr) (_fchdr->fh_type == FC_TYPE_ELS)
|
||||
#define FNIC_FC_FRAME_TYPE_FC_GS(_fchdr) (_fchdr->fh_type == FC_TYPE_CT)
|
||||
#define FNIC_FC_FRAME_CS_CTL(_fchdr) (_fchdr->fh_cs_ctl == FNIC_FC_CS_CTL)
|
||||
|
||||
#define FNIC_FC_C3_RDF (0xfff)
|
||||
#define FNIC_FC_PLOGI_RSP_RDF(_plogi_rsp) \
|
||||
(min(_plogi_rsp->u.csp_plogi.b2b_rdf_size, \
|
||||
(_plogi_rsp->spc3[4] & FNIC_FC_C3_RDF)))
|
||||
#define FNIC_FC_PLOGI_RSP_CONCUR_SEQ(_plogi_rsp) \
|
||||
(min((uint16_t) (be16_to_cpu(_plogi_rsp->els.fl_csp.sp_tot_seq)), \
|
||||
(uint16_t) (be16_to_cpu(_plogi_rsp->els.fl_cssp[2].cp_con_seq) & 0xff)))
|
||||
|
||||
/* FLOGI/PLOGI struct */
|
||||
struct fc_std_flogi {
|
||||
struct fc_frame_header fchdr;
|
||||
struct fc_els_flogi els;
|
||||
} __packed;
|
||||
|
||||
struct fc_std_els_acc_rsp {
|
||||
struct fc_frame_header fchdr;
|
||||
struct fc_els_ls_acc acc;
|
||||
} __packed;
|
||||
|
||||
struct fc_std_els_rjt_rsp {
|
||||
struct fc_frame_header fchdr;
|
||||
struct fc_els_ls_rjt rej;
|
||||
} __packed;
|
||||
|
||||
struct fc_std_els_adisc {
|
||||
struct fc_frame_header fchdr;
|
||||
struct fc_els_adisc els;
|
||||
} __packed;
|
||||
|
||||
struct fc_std_rls_acc {
|
||||
struct fc_frame_header fchdr;
|
||||
struct fc_els_rls_resp els;
|
||||
} __packed;
|
||||
|
||||
struct fc_std_abts_ba_acc {
|
||||
struct fc_frame_header fchdr;
|
||||
struct fc_ba_acc acc;
|
||||
} __packed;
|
||||
|
||||
struct fc_std_abts_ba_rjt {
|
||||
struct fc_frame_header fchdr;
|
||||
struct fc_ba_rjt rjt;
|
||||
} __packed;
|
||||
|
||||
struct fc_std_els_prli {
|
||||
struct fc_frame_header fchdr;
|
||||
struct fc_els_prli els_prli;
|
||||
struct fc_els_spp sp;
|
||||
} __packed;
|
||||
|
||||
struct fc_std_rpn_id {
|
||||
struct fc_frame_header fchdr;
|
||||
struct fc_ct_hdr fc_std_ct_hdr;
|
||||
struct fc_ns_rn_id rpn_id;
|
||||
} __packed;
|
||||
|
||||
struct fc_std_fdmi_rhba {
|
||||
struct fc_frame_header fchdr;
|
||||
struct fc_ct_hdr fc_std_ct_hdr;
|
||||
struct fc_fdmi_rhba rhba;
|
||||
} __packed;
|
||||
|
||||
struct fc_std_fdmi_rpa {
|
||||
struct fc_frame_header fchdr;
|
||||
struct fc_ct_hdr fc_std_ct_hdr;
|
||||
struct fc_fdmi_rpa rpa;
|
||||
} __packed;
|
||||
|
||||
struct fc_std_rft_id {
|
||||
struct fc_frame_header fchdr;
|
||||
struct fc_ct_hdr fc_std_ct_hdr;
|
||||
struct fc_ns_rft_id rft_id;
|
||||
} __packed;
|
||||
|
||||
struct fc_std_rff_id {
|
||||
struct fc_frame_header fchdr;
|
||||
struct fc_ct_hdr fc_std_ct_hdr;
|
||||
struct fc_ns_rff_id rff_id;
|
||||
} __packed;
|
||||
|
||||
struct fc_std_gpn_ft {
|
||||
struct fc_frame_header fchdr;
|
||||
struct fc_ct_hdr fc_std_ct_hdr;
|
||||
struct fc_ns_gid_ft gpn_ft;
|
||||
} __packed;
|
||||
|
||||
/* Accept CT_IU for GPN_FT */
|
||||
struct fc_gpn_ft_rsp_iu {
|
||||
uint8_t ctrl;
|
||||
uint8_t fcid[3];
|
||||
uint32_t rsvd;
|
||||
__be64 wwpn;
|
||||
} __packed;
|
||||
|
||||
struct fc_std_rls {
|
||||
struct fc_frame_header fchdr;
|
||||
struct fc_els_rls els;
|
||||
} __packed;
|
||||
|
||||
struct fc_std_scr {
|
||||
struct fc_frame_header fchdr;
|
||||
struct fc_els_scr scr;
|
||||
} __packed;
|
||||
|
||||
struct fc_std_rscn {
|
||||
struct fc_frame_header fchdr;
|
||||
struct fc_els_rscn els;
|
||||
} __packed;
|
||||
|
||||
struct fc_std_logo {
|
||||
struct fc_frame_header fchdr;
|
||||
struct fc_els_logo els;
|
||||
} __packed;
|
||||
|
||||
#define FNIC_ETH_FCOE_HDRS_OFFSET \
|
||||
(sizeof(struct ethhdr) + sizeof(struct fcoe_hdr))
|
||||
|
||||
#endif /* _FDLS_FC_H */
|
1005
drivers/scsi/fnic/fip.c
Normal file
1005
drivers/scsi/fnic/fip.c
Normal file
File diff suppressed because it is too large
Load Diff
159
drivers/scsi/fnic/fip.h
Normal file
159
drivers/scsi/fnic/fip.h
Normal file
|
@ -0,0 +1,159 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright 2008 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
|
||||
*/
|
||||
#ifndef _FIP_H_
|
||||
#define _FIP_H_
|
||||
|
||||
#include "fdls_fc.h"
|
||||
#include "fnic_fdls.h"
|
||||
#include <scsi/fc/fc_fip.h>
|
||||
|
||||
/* Drop the cast from the standard definition */
|
||||
#define FCOE_ALL_FCFS_MAC {0x01, 0x10, 0x18, 0x01, 0x00, 0x02}
|
||||
#define FCOE_MAX_SIZE 0x082E
|
||||
|
||||
#define FCOE_CTLR_FIPVLAN_TOV (3*1000)
|
||||
#define FCOE_CTLR_FCS_TOV (3*1000)
|
||||
#define FCOE_CTLR_MAX_SOL (5*1000)
|
||||
|
||||
#define FIP_DISC_SOL_LEN (6)
|
||||
#define FIP_VLAN_REQ_LEN (2)
|
||||
#define FIP_ENODE_KA_LEN (2)
|
||||
#define FIP_VN_KA_LEN (7)
|
||||
#define FIP_FLOGI_LEN (38)
|
||||
|
||||
enum fdls_vlan_state {
|
||||
FIP_VLAN_AVAIL,
|
||||
FIP_VLAN_SENT
|
||||
};
|
||||
|
||||
enum fdls_fip_state {
|
||||
FDLS_FIP_INIT,
|
||||
FDLS_FIP_VLAN_DISCOVERY_STARTED,
|
||||
FDLS_FIP_FCF_DISCOVERY_STARTED,
|
||||
FDLS_FIP_FLOGI_STARTED,
|
||||
FDLS_FIP_FLOGI_COMPLETE,
|
||||
};
|
||||
|
||||
/*
|
||||
* VLAN entry.
|
||||
*/
|
||||
struct fcoe_vlan {
|
||||
struct list_head list;
|
||||
uint16_t vid; /* vlan ID */
|
||||
uint16_t sol_count; /* no. of sols sent */
|
||||
uint16_t state; /* state */
|
||||
};
|
||||
|
||||
struct fip_vlan_req {
|
||||
struct ethhdr eth;
|
||||
struct fip_header fip;
|
||||
struct fip_mac_desc mac_desc;
|
||||
} __packed;
|
||||
|
||||
struct fip_vlan_notif {
|
||||
struct fip_header fip;
|
||||
struct fip_vlan_desc vlans_desc[];
|
||||
} __packed;
|
||||
|
||||
struct fip_vn_port_ka {
|
||||
struct ethhdr eth;
|
||||
struct fip_header fip;
|
||||
struct fip_mac_desc mac_desc;
|
||||
struct fip_vn_desc vn_port_desc;
|
||||
} __packed;
|
||||
|
||||
struct fip_enode_ka {
|
||||
struct ethhdr eth;
|
||||
struct fip_header fip;
|
||||
struct fip_mac_desc mac_desc;
|
||||
} __packed;
|
||||
|
||||
struct fip_cvl {
|
||||
struct fip_header fip;
|
||||
struct fip_mac_desc fcf_mac_desc;
|
||||
struct fip_wwn_desc name_desc;
|
||||
struct fip_vn_desc vn_ports_desc[];
|
||||
} __packed;
|
||||
|
||||
struct fip_flogi_desc {
|
||||
struct fip_desc fd_desc;
|
||||
uint16_t rsvd;
|
||||
struct fc_std_flogi flogi;
|
||||
} __packed;
|
||||
|
||||
struct fip_flogi_rsp_desc {
|
||||
struct fip_desc fd_desc;
|
||||
uint16_t rsvd;
|
||||
struct fc_std_flogi flogi;
|
||||
} __packed;
|
||||
|
||||
struct fip_flogi {
|
||||
struct ethhdr eth;
|
||||
struct fip_header fip;
|
||||
struct fip_flogi_desc flogi_desc;
|
||||
struct fip_mac_desc mac_desc;
|
||||
} __packed;
|
||||
|
||||
struct fip_flogi_rsp {
|
||||
struct fip_header fip;
|
||||
struct fip_flogi_rsp_desc rsp_desc;
|
||||
struct fip_mac_desc mac_desc;
|
||||
} __packed;
|
||||
|
||||
struct fip_discovery {
|
||||
struct ethhdr eth;
|
||||
struct fip_header fip;
|
||||
struct fip_mac_desc mac_desc;
|
||||
struct fip_wwn_desc name_desc;
|
||||
struct fip_size_desc fcoe_desc;
|
||||
} __packed;
|
||||
|
||||
struct fip_disc_adv {
|
||||
struct fip_header fip;
|
||||
struct fip_pri_desc prio_desc;
|
||||
struct fip_mac_desc mac_desc;
|
||||
struct fip_wwn_desc name_desc;
|
||||
struct fip_fab_desc fabric_desc;
|
||||
struct fip_fka_desc fka_adv_desc;
|
||||
} __packed;
|
||||
|
||||
void fnic_fcoe_process_vlan_resp(struct fnic *fnic, struct fip_header *fiph);
|
||||
void fnic_fcoe_fip_discovery_resp(struct fnic *fnic, struct fip_header *fiph);
|
||||
void fnic_fcoe_process_flogi_resp(struct fnic *fnic, struct fip_header *fiph);
|
||||
void fnic_work_on_fip_timer(struct work_struct *work);
|
||||
void fnic_work_on_fcs_ka_timer(struct work_struct *work);
|
||||
void fnic_fcoe_send_vlan_req(struct fnic *fnic);
|
||||
void fnic_fcoe_start_fcf_discovery(struct fnic *fnic);
|
||||
void fnic_fcoe_start_flogi(struct fnic *fnic);
|
||||
void fnic_fcoe_process_cvl(struct fnic *fnic, struct fip_header *fiph);
|
||||
void fnic_vlan_discovery_timeout(struct fnic *fnic);
|
||||
|
||||
extern struct workqueue_struct *fnic_fip_queue;
|
||||
|
||||
#ifdef FNIC_DEBUG
|
||||
static inline void
|
||||
fnic_debug_dump_fip_frame(struct fnic *fnic, struct ethhdr *eth,
|
||||
int len, char *pfx)
|
||||
{
|
||||
struct fip_header *fiph = (struct fip_header *)(eth + 1);
|
||||
u16 op = be16_to_cpu(fiph->fip_op);
|
||||
u8 sub = fiph->fip_subcode;
|
||||
|
||||
FNIC_FCS_DBG(KERN_DEBUG, fnic->host, fnic->fnic_num,
|
||||
"FIP %s packet contents: op: 0x%x sub: 0x%x (len = %d)",
|
||||
pfx, op, sub, len);
|
||||
|
||||
fnic_debug_dump(fnic, (uint8_t *)eth, len);
|
||||
}
|
||||
|
||||
#else /* FNIC_DEBUG */
|
||||
|
||||
static inline void
|
||||
fnic_debug_dump_fip_frame(struct fnic *fnic, struct ethhdr *eth,
|
||||
int len, char *pfx) {}
|
||||
#endif /* FNIC_DEBUG */
|
||||
|
||||
#endif /* _FIP_H_ */
|
|
@ -10,8 +10,10 @@
|
|||
#include <linux/netdevice.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <scsi/libfc.h>
|
||||
#include <scsi/libfcoe.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
#include <scsi/scsi_transport.h>
|
||||
#include <scsi/scsi_transport_fc.h>
|
||||
#include <scsi/fc_frame.h>
|
||||
#include "fnic_io.h"
|
||||
#include "fnic_res.h"
|
||||
#include "fnic_trace.h"
|
||||
|
@ -24,13 +26,15 @@
|
|||
#include "vnic_intr.h"
|
||||
#include "vnic_stats.h"
|
||||
#include "vnic_scsi.h"
|
||||
#include "fnic_fdls.h"
|
||||
|
||||
#define DRV_NAME "fnic"
|
||||
#define DRV_DESCRIPTION "Cisco FCoE HBA Driver"
|
||||
#define DRV_VERSION "1.7.0.0"
|
||||
#define DRV_VERSION "1.8.0.0"
|
||||
#define PFX DRV_NAME ": "
|
||||
#define DFX DRV_NAME "%d: "
|
||||
|
||||
#define FABRIC_LOGO_MAX_RETRY 3
|
||||
#define DESC_CLEAN_LOW_WATERMARK 8
|
||||
#define FNIC_UCSM_DFLT_THROTTLE_CNT_BLD 16 /* UCSM default throttle count */
|
||||
#define FNIC_MIN_IO_REQ 256 /* Min IO throttle count */
|
||||
|
@ -38,6 +42,7 @@
|
|||
#define FNIC_DFLT_IO_REQ 256 /* Default scsi_cmnd tag map entries */
|
||||
#define FNIC_DFLT_QUEUE_DEPTH 256
|
||||
#define FNIC_STATS_RATE_LIMIT 4 /* limit rate at which stats are pulled up */
|
||||
#define LUN0_DELAY_TIME 9
|
||||
|
||||
/*
|
||||
* Tag bits used for special requests.
|
||||
|
@ -75,6 +80,77 @@
|
|||
#define FNIC_DEV_RST_TERM_DONE BIT(20)
|
||||
#define FNIC_DEV_RST_ABTS_PENDING BIT(21)
|
||||
|
||||
#define FNIC_FW_RESET_TIMEOUT 60000 /* mSec */
|
||||
#define FNIC_FCOE_MAX_CMD_LEN 16
|
||||
/* Retry supported by rport (returned by PRLI service parameters) */
|
||||
#define FNIC_FC_RP_FLAGS_RETRY 0x1
|
||||
|
||||
/* Cisco vendor id */
|
||||
#define PCI_VENDOR_ID_CISCO 0x1137
|
||||
#define PCI_DEVICE_ID_CISCO_VIC_FC 0x0045 /* fc vnic */
|
||||
|
||||
/* sereno pcie switch */
|
||||
#define PCI_DEVICE_ID_CISCO_SERENO 0x004e
|
||||
#define PCI_DEVICE_ID_CISCO_CRUZ 0x007a /* Cruz */
|
||||
#define PCI_DEVICE_ID_CISCO_BODEGA 0x0131 /* Bodega */
|
||||
#define PCI_DEVICE_ID_CISCO_BEVERLY 0x025f /* Beverly */
|
||||
|
||||
/* Sereno */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_VASONA 0x004f /* vasona mezz */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_COTATI 0x0084 /* cotati mlom */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_LEXINGTON 0x0085 /* lexington pcie */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_ICEHOUSE 0x00cd /* Icehouse */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_KIRKWOODLAKE 0x00ce /* KirkwoodLake pcie */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_SUSANVILLE 0x012e /* Susanville MLOM */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_TORRANCE 0x0139 /* Torrance MLOM */
|
||||
|
||||
/* Cruz */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_CALISTOGA 0x012c /* Calistoga MLOM */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_MOUNTAINVIEW 0x0137 /* Cruz Mezz */
|
||||
/* Cruz MountTian SIOC */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_MOUNTTIAN 0x014b
|
||||
#define PCI_SUBDEVICE_ID_CISCO_CLEARLAKE 0x014d /* ClearLake pcie */
|
||||
/* Cruz MountTian2 SIOC */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_MOUNTTIAN2 0x0157
|
||||
#define PCI_SUBDEVICE_ID_CISCO_CLAREMONT 0x015d /* Claremont MLOM */
|
||||
|
||||
/* Bodega */
|
||||
/* VIC 1457 PCIe mLOM */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_BRADBURY 0x0218
|
||||
#define PCI_SUBDEVICE_ID_CISCO_BRENTWOOD 0x0217 /* VIC 1455 PCIe */
|
||||
/* VIC 1487 PCIe mLOM */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_BURLINGAME 0x021a
|
||||
#define PCI_SUBDEVICE_ID_CISCO_BAYSIDE 0x0219 /* VIC 1485 PCIe */
|
||||
/* VIC 1440 Mezz mLOM */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_BAKERSFIELD 0x0215
|
||||
#define PCI_SUBDEVICE_ID_CISCO_BOONVILLE 0x0216 /* VIC 1480 Mezz */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_BENICIA 0x024a /* VIC 1495 */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_BEAUMONT 0x024b /* VIC 1497 */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_BRISBANE 0x02af /* VIC 1467 */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_BENTON 0x02b0 /* VIC 1477 */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_TWIN_RIVER 0x02cf /* VIC 14425 */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_TWIN_PEAK 0x02d0 /* VIC 14825 */
|
||||
|
||||
/* Beverly */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_BERN 0x02de /* VIC 15420 */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_STOCKHOLM 0x02dd /* VIC 15428 */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_KRAKOW 0x02dc /* VIC 15411 */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_LUCERNE 0x02db /* VIC 15231 */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_TURKU 0x02e8 /* VIC 15238 */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_TURKU_PLUS 0x02f3 /* VIC 15237 */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_ZURICH 0x02df /* VIC 15230 */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_RIGA 0x02e0 /* VIC 15427 */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_GENEVA 0x02e1 /* VIC 15422 */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_HELSINKI 0x02e4 /* VIC 15235 */
|
||||
#define PCI_SUBDEVICE_ID_CISCO_GOTHENBURG 0x02f2 /* VIC 15425 */
|
||||
|
||||
struct fnic_pcie_device {
|
||||
u32 device;
|
||||
u8 *desc;
|
||||
u32 subsystem_device;
|
||||
u8 *subsys_desc;
|
||||
};
|
||||
|
||||
/*
|
||||
* fnic private data per SCSI command.
|
||||
* These fields are locked by the hashed io_req_lock.
|
||||
|
@ -127,8 +203,38 @@ static inline u64 fnic_flags_and_state(struct scsi_cmnd *cmd)
|
|||
#define fnic_clear_state_flags(fnicp, st_flags) \
|
||||
__fnic_set_state_flags(fnicp, st_flags, 1)
|
||||
|
||||
enum reset_states {
|
||||
NOT_IN_PROGRESS = 0,
|
||||
IN_PROGRESS,
|
||||
RESET_ERROR
|
||||
};
|
||||
|
||||
enum rscn_type {
|
||||
NOT_PC_RSCN = 0,
|
||||
PC_RSCN
|
||||
};
|
||||
|
||||
enum pc_rscn_handling_status {
|
||||
PC_RSCN_HANDLING_NOT_IN_PROGRESS = 0,
|
||||
PC_RSCN_HANDLING_IN_PROGRESS
|
||||
};
|
||||
|
||||
enum pc_rscn_handling_feature {
|
||||
PC_RSCN_HANDLING_FEATURE_OFF = 0,
|
||||
PC_RSCN_HANDLING_FEATURE_ON
|
||||
};
|
||||
|
||||
extern unsigned int fnic_fdmi_support;
|
||||
extern unsigned int fnic_log_level;
|
||||
extern unsigned int io_completions;
|
||||
extern struct workqueue_struct *fnic_event_queue;
|
||||
|
||||
extern unsigned int pc_rscn_handling_feature_flag;
|
||||
extern spinlock_t reset_fnic_list_lock;
|
||||
extern struct list_head reset_fnic_list;
|
||||
extern struct workqueue_struct *reset_fnic_work_queue;
|
||||
extern struct work_struct reset_fnic_work;
|
||||
|
||||
|
||||
#define FNIC_MAIN_LOGGING 0x01
|
||||
#define FNIC_FCS_LOGGING 0x02
|
||||
|
@ -155,6 +261,12 @@ do { \
|
|||
"fnic<%d>: %s: %d: " fmt, fnic_num,\
|
||||
__func__, __LINE__, ##args);)
|
||||
|
||||
#define FNIC_FIP_DBG(kern_level, host, fnic_num, fmt, args...) \
|
||||
FNIC_CHECK_LOGGING(FNIC_FCS_LOGGING, \
|
||||
shost_printk(kern_level, host, \
|
||||
"fnic<%d>: %s: %d: " fmt, fnic_num,\
|
||||
__func__, __LINE__, ##args);)
|
||||
|
||||
#define FNIC_SCSI_DBG(kern_level, host, fnic_num, fmt, args...) \
|
||||
FNIC_CHECK_LOGGING(FNIC_SCSI_LOGGING, \
|
||||
shost_printk(kern_level, host, \
|
||||
|
@ -213,12 +325,26 @@ enum fnic_state {
|
|||
|
||||
struct mempool;
|
||||
|
||||
enum fnic_role_e {
|
||||
FNIC_ROLE_FCP_INITIATOR = 0,
|
||||
};
|
||||
|
||||
enum fnic_evt {
|
||||
FNIC_EVT_START_VLAN_DISC = 1,
|
||||
FNIC_EVT_START_FCF_DISC = 2,
|
||||
FNIC_EVT_MAX,
|
||||
};
|
||||
|
||||
struct fnic_frame_list {
|
||||
/*
|
||||
* Link to frame lists
|
||||
*/
|
||||
struct list_head links;
|
||||
void *fp;
|
||||
int frame_len;
|
||||
int rx_ethhdr_stripped;
|
||||
};
|
||||
|
||||
struct fnic_event {
|
||||
struct list_head list;
|
||||
struct fnic *fnic;
|
||||
|
@ -235,8 +361,9 @@ struct fnic_cpy_wq {
|
|||
/* Per-instance private data structure */
|
||||
struct fnic {
|
||||
int fnic_num;
|
||||
struct fc_lport *lport;
|
||||
struct fcoe_ctlr ctlr; /* FIP FCoE controller structure */
|
||||
enum fnic_role_e role;
|
||||
struct fnic_iport_s iport;
|
||||
struct Scsi_Host *host;
|
||||
struct vnic_dev_bar bar0;
|
||||
|
||||
struct fnic_msix_entry msix[FNIC_MSIX_INTR_MAX];
|
||||
|
@ -255,6 +382,7 @@ struct fnic {
|
|||
unsigned int wq_count;
|
||||
unsigned int cq_count;
|
||||
|
||||
struct completion reset_completion_wait;
|
||||
struct mutex sgreset_mutex;
|
||||
spinlock_t sgreset_lock; /* lock for sgreset */
|
||||
struct scsi_cmnd *sgreset_sc;
|
||||
|
@ -268,25 +396,27 @@ struct fnic {
|
|||
u32 vlan_hw_insert:1; /* let hw insert the tag */
|
||||
u32 in_remove:1; /* fnic device in removal */
|
||||
u32 stop_rx_link_events:1; /* stop proc. rx frames, link events */
|
||||
u32 link_events:1; /* set when we get any link event*/
|
||||
|
||||
struct completion *remove_wait; /* device remove thread blocks */
|
||||
|
||||
struct completion *fw_reset_done;
|
||||
u32 reset_in_progress;
|
||||
atomic_t in_flight; /* io counter */
|
||||
bool internal_reset_inprogress;
|
||||
u32 _reserved; /* fill hole */
|
||||
unsigned long state_flags; /* protected by host lock */
|
||||
enum fnic_state state;
|
||||
spinlock_t fnic_lock;
|
||||
unsigned long lock_flags;
|
||||
|
||||
u16 vlan_id; /* VLAN tag including priority */
|
||||
u8 data_src_addr[ETH_ALEN];
|
||||
u64 fcp_input_bytes; /* internal statistic */
|
||||
u64 fcp_output_bytes; /* internal statistic */
|
||||
u32 link_down_cnt;
|
||||
u32 soft_reset_count;
|
||||
int link_status;
|
||||
|
||||
struct list_head list;
|
||||
struct list_head links;
|
||||
struct pci_dev *pdev;
|
||||
struct vnic_fc_config config;
|
||||
struct vnic_dev *vdev;
|
||||
|
@ -306,19 +436,29 @@ struct fnic {
|
|||
struct work_struct link_work;
|
||||
struct work_struct frame_work;
|
||||
struct work_struct flush_work;
|
||||
struct sk_buff_head frame_queue;
|
||||
struct sk_buff_head tx_queue;
|
||||
struct list_head frame_queue;
|
||||
struct list_head tx_queue;
|
||||
mempool_t *frame_pool;
|
||||
mempool_t *frame_elem_pool;
|
||||
struct work_struct tport_work;
|
||||
struct list_head tport_event_list;
|
||||
|
||||
char subsys_desc[14];
|
||||
int subsys_desc_len;
|
||||
int pc_rscn_handling_status;
|
||||
|
||||
/*** FIP related data members -- start ***/
|
||||
void (*set_vlan)(struct fnic *, u16 vlan);
|
||||
struct work_struct fip_frame_work;
|
||||
struct sk_buff_head fip_frame_queue;
|
||||
struct work_struct fip_timer_work;
|
||||
struct list_head fip_frame_queue;
|
||||
struct timer_list fip_timer;
|
||||
struct list_head vlans;
|
||||
spinlock_t vlans_lock;
|
||||
|
||||
struct work_struct event_work;
|
||||
struct list_head evlist;
|
||||
struct timer_list retry_fip_timer;
|
||||
struct timer_list fcs_ka_timer;
|
||||
struct timer_list enode_ka_timer;
|
||||
struct timer_list vn_ka_timer;
|
||||
struct list_head vlan_list;
|
||||
/*** FIP related data members -- end ***/
|
||||
|
||||
/* copy work queue cache line section */
|
||||
|
@ -341,11 +481,6 @@ struct fnic {
|
|||
____cacheline_aligned struct vnic_intr intr[FNIC_MSIX_INTR_MAX];
|
||||
};
|
||||
|
||||
static inline struct fnic *fnic_from_ctlr(struct fcoe_ctlr *fip)
|
||||
{
|
||||
return container_of(fip, struct fnic, ctlr);
|
||||
}
|
||||
|
||||
extern struct workqueue_struct *fnic_event_queue;
|
||||
extern struct workqueue_struct *fnic_fip_queue;
|
||||
extern const struct attribute_group *fnic_host_groups[];
|
||||
|
@ -356,29 +491,29 @@ int fnic_set_intr_mode_msix(struct fnic *fnic);
|
|||
void fnic_free_intr(struct fnic *fnic);
|
||||
int fnic_request_intr(struct fnic *fnic);
|
||||
|
||||
int fnic_send(struct fc_lport *, struct fc_frame *);
|
||||
void fnic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf);
|
||||
void fnic_handle_frame(struct work_struct *work);
|
||||
void fnic_tport_event_handler(struct work_struct *work);
|
||||
void fnic_handle_link(struct work_struct *work);
|
||||
void fnic_handle_event(struct work_struct *work);
|
||||
void fdls_reclaim_oxid_handler(struct work_struct *work);
|
||||
void fdls_schedule_oxid_free(struct fnic_iport_s *iport, uint16_t *active_oxid);
|
||||
void fdls_schedule_oxid_free_retry_work(struct work_struct *work);
|
||||
int fnic_rq_cmpl_handler(struct fnic *fnic, int);
|
||||
int fnic_alloc_rq_frame(struct vnic_rq *rq);
|
||||
void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf);
|
||||
void fnic_flush_tx(struct work_struct *work);
|
||||
void fnic_eth_send(struct fcoe_ctlr *, struct sk_buff *skb);
|
||||
void fnic_set_port_id(struct fc_lport *, u32, struct fc_frame *);
|
||||
void fnic_update_mac(struct fc_lport *, u8 *new);
|
||||
void fnic_update_mac_locked(struct fnic *, u8 *new);
|
||||
|
||||
int fnic_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
|
||||
int fnic_abort_cmd(struct scsi_cmnd *);
|
||||
int fnic_device_reset(struct scsi_cmnd *);
|
||||
int fnic_host_reset(struct scsi_cmnd *);
|
||||
int fnic_reset(struct Scsi_Host *);
|
||||
void fnic_scsi_cleanup(struct fc_lport *);
|
||||
void fnic_scsi_abort_io(struct fc_lport *);
|
||||
void fnic_empty_scsi_cleanup(struct fc_lport *);
|
||||
void fnic_exch_mgr_reset(struct fc_lport *, u32, u32);
|
||||
int fnic_eh_host_reset_handler(struct scsi_cmnd *sc);
|
||||
int fnic_host_reset(struct Scsi_Host *shost);
|
||||
void fnic_reset(struct Scsi_Host *shost);
|
||||
int fnic_issue_fc_host_lip(struct Scsi_Host *shost);
|
||||
void fnic_get_host_port_state(struct Scsi_Host *shost);
|
||||
void fnic_scsi_fcpio_reset(struct fnic *fnic);
|
||||
int fnic_wq_copy_cmpl_handler(struct fnic *fnic, int copy_work_to_do, unsigned int cq_index);
|
||||
int fnic_wq_cmpl_handler(struct fnic *fnic, int);
|
||||
int fnic_flogi_reg_handler(struct fnic *fnic, u32);
|
||||
|
@ -390,14 +525,15 @@ const char *fnic_state_to_str(unsigned int state);
|
|||
void fnic_mq_map_queues_cpus(struct Scsi_Host *host);
|
||||
void fnic_log_q_error(struct fnic *fnic);
|
||||
void fnic_handle_link_event(struct fnic *fnic);
|
||||
|
||||
int fnic_stats_debugfs_init(struct fnic *fnic);
|
||||
void fnic_stats_debugfs_remove(struct fnic *fnic);
|
||||
int fnic_is_abts_pending(struct fnic *, struct scsi_cmnd *);
|
||||
|
||||
void fnic_handle_fip_frame(struct work_struct *work);
|
||||
void fnic_reset_work_handler(struct work_struct *work);
|
||||
void fnic_handle_fip_event(struct fnic *fnic);
|
||||
void fnic_fcoe_reset_vlans(struct fnic *fnic);
|
||||
void fnic_fcoe_evlist_free(struct fnic *fnic);
|
||||
extern void fnic_handle_fip_timer(struct fnic *fnic);
|
||||
extern void fnic_handle_fip_timer(struct timer_list *t);
|
||||
|
||||
static inline int
|
||||
fnic_chk_state_flags_locked(struct fnic *fnic, unsigned long st_flags)
|
||||
|
@ -406,4 +542,90 @@ fnic_chk_state_flags_locked(struct fnic *fnic, unsigned long st_flags)
|
|||
}
|
||||
void __fnic_set_state_flags(struct fnic *, unsigned long, unsigned long);
|
||||
void fnic_dump_fchost_stats(struct Scsi_Host *, struct fc_host_statistics *);
|
||||
void fnic_free_txq(struct list_head *head);
|
||||
int fnic_get_desc_by_devid(struct pci_dev *pdev, char **desc,
|
||||
char **subsys_desc);
|
||||
void fnic_fdls_link_status_change(struct fnic *fnic, int linkup);
|
||||
void fnic_delete_fcp_tports(struct fnic *fnic);
|
||||
void fnic_flush_tport_event_list(struct fnic *fnic);
|
||||
int fnic_count_ioreqs_wq(struct fnic *fnic, u32 hwq, u32 portid);
|
||||
unsigned int fnic_count_ioreqs(struct fnic *fnic, u32 portid);
|
||||
unsigned int fnic_count_all_ioreqs(struct fnic *fnic);
|
||||
unsigned int fnic_count_lun_ioreqs_wq(struct fnic *fnic, u32 hwq,
|
||||
struct scsi_device *device);
|
||||
unsigned int fnic_count_lun_ioreqs(struct fnic *fnic,
|
||||
struct scsi_device *device);
|
||||
void fnic_scsi_unload(struct fnic *fnic);
|
||||
void fnic_scsi_unload_cleanup(struct fnic *fnic);
|
||||
int fnic_get_debug_info(struct stats_debug_info *info,
|
||||
struct fnic *fnic);
|
||||
|
||||
struct fnic_scsi_iter_data {
|
||||
struct fnic *fnic;
|
||||
void *data1;
|
||||
void *data2;
|
||||
bool (*fn)(struct fnic *fnic, struct scsi_cmnd *sc,
|
||||
void *data1, void *data2);
|
||||
};
|
||||
|
||||
static inline bool
|
||||
fnic_io_iter_handler(struct scsi_cmnd *sc, void *iter_data)
|
||||
{
|
||||
struct fnic_scsi_iter_data *iter = iter_data;
|
||||
|
||||
return iter->fn(iter->fnic, sc, iter->data1, iter->data2);
|
||||
}
|
||||
|
||||
static inline void
|
||||
fnic_scsi_io_iter(struct fnic *fnic,
|
||||
bool (*fn)(struct fnic *fnic, struct scsi_cmnd *sc,
|
||||
void *data1, void *data2),
|
||||
void *data1, void *data2)
|
||||
{
|
||||
struct fnic_scsi_iter_data iter_data = {
|
||||
.fn = fn,
|
||||
.fnic = fnic,
|
||||
.data1 = data1,
|
||||
.data2 = data2,
|
||||
};
|
||||
scsi_host_busy_iter(fnic->host, fnic_io_iter_handler, &iter_data);
|
||||
}
|
||||
|
||||
#ifdef FNIC_DEBUG
|
||||
static inline void
|
||||
fnic_debug_dump(struct fnic *fnic, uint8_t *u8arr, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i = i+8) {
|
||||
FNIC_FCS_DBG(KERN_DEBUG, fnic->host, fnic->fnic_num,
|
||||
"%d: %02x %02x %02x %02x %02x %02x %02x %02x", i / 8,
|
||||
u8arr[i + 0], u8arr[i + 1], u8arr[i + 2], u8arr[i + 3],
|
||||
u8arr[i + 4], u8arr[i + 5], u8arr[i + 6], u8arr[i + 7]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
fnic_debug_dump_fc_frame(struct fnic *fnic, struct fc_frame_header *fchdr,
|
||||
int len, char *pfx)
|
||||
{
|
||||
uint32_t s_id, d_id;
|
||||
|
||||
s_id = ntoh24(fchdr->fh_s_id);
|
||||
d_id = ntoh24(fchdr->fh_d_id);
|
||||
FNIC_FCS_DBG(KERN_DEBUG, fnic->host, fnic->fnic_num,
|
||||
"%s packet contents: sid/did/type/oxid = 0x%x/0x%x/0x%x/0x%x (len = %d)\n",
|
||||
pfx, s_id, d_id, fchdr->fh_type,
|
||||
FNIC_STD_GET_OX_ID(fchdr), len);
|
||||
|
||||
fnic_debug_dump(fnic, (uint8_t *)fchdr, len);
|
||||
|
||||
}
|
||||
#else /* FNIC_DEBUG */
|
||||
static inline void
|
||||
fnic_debug_dump(struct fnic *fnic, uint8_t *u8arr, int len) {}
|
||||
static inline void
|
||||
fnic_debug_dump_fc_frame(struct fnic *fnic, struct fc_frame_header *fchdr,
|
||||
uint32_t len, char *pfx) {}
|
||||
#endif /* FNIC_DEBUG */
|
||||
#endif /* _FNIC_H_ */
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
static ssize_t fnic_show_state(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct fc_lport *lp = shost_priv(class_to_shost(dev));
|
||||
struct fnic *fnic = lport_priv(lp);
|
||||
struct fnic *fnic =
|
||||
*((struct fnic **) shost_priv(class_to_shost(dev)));
|
||||
|
||||
return sysfs_emit(buf, "%s\n", fnic_state_str[fnic->state]);
|
||||
}
|
||||
|
@ -26,9 +26,13 @@ static ssize_t fnic_show_drv_version(struct device *dev,
|
|||
static ssize_t fnic_show_link_state(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct fc_lport *lp = shost_priv(class_to_shost(dev));
|
||||
struct fnic *fnic =
|
||||
*((struct fnic **) shost_priv(class_to_shost(dev)));
|
||||
|
||||
return sysfs_emit(buf, "%s\n", (lp->link_up) ? "Link Up" : "Link Down");
|
||||
return sysfs_emit(buf, "%s\n",
|
||||
((fnic->iport.state != FNIC_IPORT_STATE_INIT) &&
|
||||
(fnic->iport.state != FNIC_IPORT_STATE_LINK_WAIT)) ?
|
||||
"Link Up" : "Link Down");
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(fnic_state, S_IRUGO, fnic_show_state, NULL);
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
#include <linux/vmalloc.h>
|
||||
#include "fnic.h"
|
||||
|
||||
extern int fnic_get_debug_info(struct stats_debug_info *debug_buffer,
|
||||
struct fnic *fnic);
|
||||
|
||||
static struct dentry *fnic_trace_debugfs_root;
|
||||
static struct dentry *fnic_trace_debugfs_file;
|
||||
static struct dentry *fnic_trace_enable;
|
||||
|
@ -593,6 +596,7 @@ static int fnic_stats_debugfs_open(struct inode *inode,
|
|||
debug->buf_size = buf_size;
|
||||
memset((void *)debug->debug_buffer, 0, buf_size);
|
||||
debug->buffer_len = fnic_get_stats_data(debug, fnic_stats);
|
||||
debug->buffer_len += fnic_get_debug_info(debug, fnic);
|
||||
|
||||
file->private_data = debug;
|
||||
|
||||
|
@ -673,26 +677,25 @@ static const struct file_operations fnic_reset_debugfs_fops = {
|
|||
* It will create file stats and reset_stats under statistics/host# directory
|
||||
* to log per fnic stats.
|
||||
*/
|
||||
void fnic_stats_debugfs_init(struct fnic *fnic)
|
||||
int fnic_stats_debugfs_init(struct fnic *fnic)
|
||||
{
|
||||
char name[16];
|
||||
|
||||
snprintf(name, sizeof(name), "host%d", fnic->lport->host->host_no);
|
||||
snprintf(name, sizeof(name), "host%d", fnic->host->host_no);
|
||||
|
||||
fnic->fnic_stats_debugfs_host = debugfs_create_dir(name,
|
||||
fnic_stats_debugfs_root);
|
||||
|
||||
fnic->fnic_stats_debugfs_file = debugfs_create_file("stats",
|
||||
S_IFREG|S_IRUGO|S_IWUSR,
|
||||
fnic->fnic_stats_debugfs_host,
|
||||
fnic,
|
||||
&fnic_stats_debugfs_fops);
|
||||
|
||||
fnic->fnic_reset_debugfs_file = debugfs_create_file("reset_stats",
|
||||
S_IFREG|S_IRUGO|S_IWUSR,
|
||||
fnic->fnic_stats_debugfs_host,
|
||||
fnic,
|
||||
&fnic_reset_debugfs_fops);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
File diff suppressed because it is too large
Load Diff
434
drivers/scsi/fnic/fnic_fdls.h
Normal file
434
drivers/scsi/fnic/fnic_fdls.h
Normal file
|
@ -0,0 +1,434 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright 2008 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _FNIC_FDLS_H_
|
||||
#define _FNIC_FDLS_H_
|
||||
|
||||
#include "fnic_stats.h"
|
||||
#include "fdls_fc.h"
|
||||
|
||||
/* FDLS - Fabric discovery and login services
|
||||
* -> VLAN discovery
|
||||
* -> retry every retry delay seconds until it succeeds.
|
||||
* <- List of VLANs
|
||||
*
|
||||
* -> Solicitation
|
||||
* <- Solicitation response (Advertisement)
|
||||
*
|
||||
* -> FCF selection & FLOGI ( FLOGI timeout - 2 * E_D_TOV)
|
||||
* <- FLOGI response
|
||||
*
|
||||
* -> FCF keep alive
|
||||
* <- FCF keep alive
|
||||
*
|
||||
* -> PLOGI to FFFFFC (DNS) (PLOGI timeout - 2 * R_A_TOV)
|
||||
* -> ABTS if timeout (ABTS tomeout - 2 * R_A_TOV)
|
||||
* <- PLOGI response
|
||||
* -> Retry PLOGI to FFFFFC (DNS) - Number of retries from vnic.cfg
|
||||
*
|
||||
* -> SCR to FFFFFC (DNS) (SCR timeout - 2 * R_A_TOV)
|
||||
* -> ABTS if timeout (ABTS tomeout - 2 * R_A_TOV)
|
||||
* <- SCR response
|
||||
* -> Retry SCR - Number of retries 2
|
||||
*
|
||||
* -> GPN_FT to FFFFFC (GPN_FT timeout - 2 * R_A_TOV)a
|
||||
* -> Retry on BUSY until it succeeds
|
||||
* -> Retry on BUSY until it succeeds
|
||||
* -> 2 retries on timeout
|
||||
*
|
||||
* -> RFT_ID to FFFFFC (DNS) (RFT_ID timeout - 3 * R_A_TOV)
|
||||
* -> ABTS if timeout (ABTS tomeout - 2 * R_A_TOV)
|
||||
* -> Retry RFT_ID to FFFFFC (DNS) (Number of retries 2 )
|
||||
* -> Ignore if both retires fail.
|
||||
*
|
||||
* Session establishment with targets
|
||||
* For each PWWN
|
||||
* -> PLOGI to FCID of that PWWN (PLOGI timeout 2 * R_A_TOV)
|
||||
* -> ABTS if timeout (ABTS tomeout - 2 * R_A_TOV)
|
||||
* <- PLOGI response
|
||||
* -> Retry PLOGI. Num retries using vnic.cfg
|
||||
*
|
||||
* -> PRLI to FCID of that PWWN (PRLI timeout 2 * R_A_TOV)
|
||||
* -> ABTS if timeout (ABTS tomeout - 2 * R_A_TOV)
|
||||
* <- PRLI response
|
||||
* -> Retry PRLI. Num retries using vnic.cfg
|
||||
*
|
||||
*/
|
||||
|
||||
#define FDLS_RETRY_COUNT 2
|
||||
|
||||
/*
|
||||
* OXID encoding:
|
||||
* bits 0-8: oxid idx - allocated from poool
|
||||
* bits 9-13: oxid frame code from fnic_oxid_frame_type_e
|
||||
* bits 14-15: all zeros
|
||||
*/
|
||||
#define FNIC_OXID_POOL_SZ (512) /* always power of 2 */
|
||||
#define FNIC_OXID_ENCODE(idx, frame_type) (frame_type | idx)
|
||||
#define FNIC_FRAME_MASK 0xFE00
|
||||
#define FNIC_FRAME_TYPE(oxid) (oxid & FNIC_FRAME_MASK)
|
||||
#define FNIC_OXID_IDX(oxid) ((oxid) & (FNIC_OXID_POOL_SZ - 1))
|
||||
|
||||
#define OXID_RECLAIM_TOV(iport) (2 * iport->r_a_tov) /* in milliseconds */
|
||||
|
||||
#define FNIC_FDLS_FABRIC_ABORT_ISSUED 0x1
|
||||
#define FNIC_FDLS_FPMA_LEARNT 0x2
|
||||
|
||||
/* tport flags */
|
||||
#define FNIC_FDLS_TPORT_IN_GPN_FT_LIST 0x1
|
||||
#define FNIC_FDLS_TGT_ABORT_ISSUED 0x2
|
||||
#define FNIC_FDLS_TPORT_SEND_ADISC 0x4
|
||||
#define FNIC_FDLS_RETRY_FRAME 0x8
|
||||
#define FNIC_FDLS_TPORT_BUSY 0x10
|
||||
#define FNIC_FDLS_TPORT_TERMINATING 0x20
|
||||
#define FNIC_FDLS_TPORT_DELETED 0x40
|
||||
#define FNIC_FDLS_SCSI_REGISTERED 0x200
|
||||
|
||||
/* Retry supported by rport(returned by prli service parameters) */
|
||||
#define FDLS_FC_RP_FLAGS_RETRY 0x1
|
||||
|
||||
#define fdls_set_state(_fdls_fabric, _state) ((_fdls_fabric)->state = _state)
|
||||
#define fdls_get_state(_fdls_fabric) ((_fdls_fabric)->state)
|
||||
|
||||
#define FNIC_FDMI_ACTIVE 0x8
|
||||
#define FNIC_FIRST_LINK_UP 0x2
|
||||
|
||||
#define fdls_set_tport_state(_tport, _state) (_tport->state = _state)
|
||||
#define fdls_get_tport_state(_tport) (_tport->state)
|
||||
|
||||
#define FNIC_PORTSPEED_10GBIT 1
|
||||
#define FNIC_FRAME_HT_ROOM (2148)
|
||||
#define FNIC_FCOE_FRAME_MAXSZ (2112)
|
||||
|
||||
|
||||
#define FNIC_FRAME_TYPE_FABRIC_FLOGI 0x1000
|
||||
#define FNIC_FRAME_TYPE_FABRIC_PLOGI 0x1200
|
||||
#define FNIC_FRAME_TYPE_FABRIC_RPN 0x1400
|
||||
#define FNIC_FRAME_TYPE_FABRIC_RFT 0x1600
|
||||
#define FNIC_FRAME_TYPE_FABRIC_RFF 0x1800
|
||||
#define FNIC_FRAME_TYPE_FABRIC_SCR 0x1A00
|
||||
#define FNIC_FRAME_TYPE_FABRIC_GPN_FT 0x1C00
|
||||
#define FNIC_FRAME_TYPE_FABRIC_LOGO 0x1E00
|
||||
#define FNIC_FRAME_TYPE_FDMI_PLOGI 0x2000
|
||||
#define FNIC_FRAME_TYPE_FDMI_RHBA 0x2200
|
||||
#define FNIC_FRAME_TYPE_FDMI_RPA 0x2400
|
||||
#define FNIC_FRAME_TYPE_TGT_PLOGI 0x2600
|
||||
#define FNIC_FRAME_TYPE_TGT_PRLI 0x2800
|
||||
#define FNIC_FRAME_TYPE_TGT_ADISC 0x2A00
|
||||
#define FNIC_FRAME_TYPE_TGT_LOGO 0x2C00
|
||||
|
||||
struct fnic_fip_fcf_s {
|
||||
uint16_t vlan_id;
|
||||
uint8_t fcf_mac[6];
|
||||
uint8_t fcf_priority;
|
||||
uint32_t fka_adv_period;
|
||||
uint8_t ka_disabled;
|
||||
};
|
||||
|
||||
enum fnic_fdls_state_e {
|
||||
FDLS_STATE_INIT = 0,
|
||||
FDLS_STATE_LINKDOWN,
|
||||
FDLS_STATE_FABRIC_LOGO,
|
||||
FDLS_STATE_FLOGO_DONE,
|
||||
FDLS_STATE_FABRIC_FLOGI,
|
||||
FDLS_STATE_FABRIC_PLOGI,
|
||||
FDLS_STATE_RPN_ID,
|
||||
FDLS_STATE_REGISTER_FC4_TYPES,
|
||||
FDLS_STATE_REGISTER_FC4_FEATURES,
|
||||
FDLS_STATE_SCR,
|
||||
FDLS_STATE_GPN_FT,
|
||||
FDLS_STATE_TGT_DISCOVERY,
|
||||
FDLS_STATE_RSCN_GPN_FT,
|
||||
FDLS_STATE_SEND_GPNFT
|
||||
};
|
||||
|
||||
struct fnic_fdls_fabric_s {
|
||||
enum fnic_fdls_state_e state;
|
||||
uint32_t flags;
|
||||
struct list_head tport_list; /* List of discovered tports */
|
||||
struct timer_list retry_timer;
|
||||
int del_timer_inprogress;
|
||||
int del_fdmi_timer_inprogress;
|
||||
int retry_counter;
|
||||
int timer_pending;
|
||||
int fdmi_retry;
|
||||
struct timer_list fdmi_timer;
|
||||
int fdmi_pending;
|
||||
};
|
||||
|
||||
struct fnic_fdls_fip_s {
|
||||
uint32_t state;
|
||||
uint32_t flogi_retry;
|
||||
};
|
||||
|
||||
/* Message to tport_event_handler */
|
||||
enum fnic_tgt_msg_id {
|
||||
TGT_EV_NONE = 0,
|
||||
TGT_EV_RPORT_ADD,
|
||||
TGT_EV_RPORT_DEL,
|
||||
TGT_EV_TPORT_DELETE,
|
||||
TGT_EV_REMOVE
|
||||
};
|
||||
|
||||
struct fnic_tport_event_s {
|
||||
struct list_head links;
|
||||
enum fnic_tgt_msg_id event;
|
||||
void *arg1;
|
||||
};
|
||||
|
||||
enum fdls_tgt_state_e {
|
||||
FDLS_TGT_STATE_INIT = 0,
|
||||
FDLS_TGT_STATE_PLOGI,
|
||||
FDLS_TGT_STATE_PRLI,
|
||||
FDLS_TGT_STATE_READY,
|
||||
FDLS_TGT_STATE_LOGO_RECEIVED,
|
||||
FDLS_TGT_STATE_ADISC,
|
||||
FDL_TGT_STATE_PLOGO,
|
||||
FDLS_TGT_STATE_OFFLINING,
|
||||
FDLS_TGT_STATE_OFFLINE
|
||||
};
|
||||
|
||||
struct fnic_tport_s {
|
||||
struct list_head links; /* To link the tports */
|
||||
enum fdls_tgt_state_e state;
|
||||
uint32_t flags;
|
||||
uint32_t fcid;
|
||||
uint64_t wwpn;
|
||||
uint64_t wwnn;
|
||||
uint16_t active_oxid;
|
||||
uint16_t tgt_flags;
|
||||
atomic_t in_flight; /* io counter */
|
||||
uint16_t max_payload_size;
|
||||
uint16_t r_a_tov;
|
||||
uint16_t e_d_tov;
|
||||
uint16_t lun0_delay;
|
||||
int max_concur_seqs;
|
||||
uint32_t fcp_csp;
|
||||
struct timer_list retry_timer;
|
||||
int del_timer_inprogress;
|
||||
int retry_counter;
|
||||
int timer_pending;
|
||||
unsigned int num_pending_cmds;
|
||||
int nexus_restart_count;
|
||||
int exch_reset_in_progress;
|
||||
void *iport;
|
||||
struct work_struct tport_del_work;
|
||||
struct completion *tport_del_done;
|
||||
struct fc_rport *rport;
|
||||
char str_wwpn[20];
|
||||
char str_wwnn[20];
|
||||
};
|
||||
|
||||
/* OXID pool related structures */
|
||||
struct reclaim_entry_s {
|
||||
struct list_head links;
|
||||
/* oxid that needs to be freed after 2*r_a_tov */
|
||||
uint16_t oxid_idx;
|
||||
/* in jiffies. Use this to waiting time */
|
||||
unsigned long expires;
|
||||
unsigned long *bitmap;
|
||||
};
|
||||
|
||||
/* used for allocating oxids for fabric and fdmi requests */
|
||||
struct fnic_oxid_pool_s {
|
||||
DECLARE_BITMAP(bitmap, FNIC_OXID_POOL_SZ);
|
||||
int sz; /* size of the pool or block */
|
||||
int next_idx; /* used for cycling through the oxid pool */
|
||||
|
||||
/* retry schedule free */
|
||||
DECLARE_BITMAP(pending_schedule_free, FNIC_OXID_POOL_SZ);
|
||||
struct delayed_work schedule_oxid_free_retry;
|
||||
|
||||
/* List of oxids that need to be freed and reclaimed.
|
||||
* This list is shared by all the oxid pools
|
||||
*/
|
||||
struct list_head oxid_reclaim_list;
|
||||
/* Work associated with reclaim list */
|
||||
struct delayed_work oxid_reclaim_work;
|
||||
};
|
||||
|
||||
/* iport */
|
||||
enum fnic_iport_state_e {
|
||||
FNIC_IPORT_STATE_INIT = 0,
|
||||
FNIC_IPORT_STATE_LINK_WAIT,
|
||||
FNIC_IPORT_STATE_FIP,
|
||||
FNIC_IPORT_STATE_FABRIC_DISC,
|
||||
FNIC_IPORT_STATE_READY
|
||||
};
|
||||
|
||||
struct fnic_iport_s {
|
||||
enum fnic_iport_state_e state;
|
||||
struct fnic *fnic;
|
||||
uint64_t boot_time;
|
||||
uint32_t flags;
|
||||
int usefip;
|
||||
uint8_t hwmac[6]; /* HW MAC Addr */
|
||||
uint8_t fpma[6]; /* Fabric Provided MA */
|
||||
uint8_t fcfmac[6]; /* MAC addr of Fabric */
|
||||
uint16_t vlan_id;
|
||||
uint32_t fcid;
|
||||
|
||||
/* oxid pool */
|
||||
struct fnic_oxid_pool_s oxid_pool;
|
||||
|
||||
/*
|
||||
* fabric reqs are serialized and only one req at a time.
|
||||
* Tracking the oxid for sending abort
|
||||
*/
|
||||
uint16_t active_oxid_fabric_req;
|
||||
/* fdmi only */
|
||||
uint16_t active_oxid_fdmi_plogi;
|
||||
uint16_t active_oxid_fdmi_rhba;
|
||||
uint16_t active_oxid_fdmi_rpa;
|
||||
|
||||
struct fnic_fip_fcf_s selected_fcf;
|
||||
struct fnic_fdls_fip_s fip;
|
||||
struct fnic_fdls_fabric_s fabric;
|
||||
struct list_head tport_list;
|
||||
struct list_head tport_list_pending_del;
|
||||
/* list of tports for which we are yet to send PLOGO */
|
||||
struct list_head inprocess_tport_list;
|
||||
struct list_head deleted_tport_list;
|
||||
struct work_struct tport_event_work;
|
||||
uint32_t e_d_tov; /* msec */
|
||||
uint32_t r_a_tov; /* msec */
|
||||
uint32_t link_supported_speeds;
|
||||
uint32_t max_flogi_retries;
|
||||
uint32_t max_plogi_retries;
|
||||
uint32_t plogi_timeout;
|
||||
uint32_t service_params;
|
||||
uint64_t wwpn;
|
||||
uint64_t wwnn;
|
||||
uint16_t max_payload_size;
|
||||
spinlock_t deleted_tport_lst_lock;
|
||||
struct completion *flogi_reg_done;
|
||||
struct fnic_iport_stats iport_stats;
|
||||
char str_wwpn[20];
|
||||
char str_wwnn[20];
|
||||
};
|
||||
|
||||
struct rport_dd_data_s {
|
||||
struct fnic_tport_s *tport;
|
||||
struct fnic_iport_s *iport;
|
||||
};
|
||||
|
||||
enum fnic_recv_frame_type_e {
|
||||
FNIC_FABRIC_FLOGI_RSP = 1,
|
||||
FNIC_FABRIC_PLOGI_RSP,
|
||||
FNIC_FABRIC_RPN_RSP,
|
||||
FNIC_FABRIC_RFT_RSP,
|
||||
FNIC_FABRIC_RFF_RSP,
|
||||
FNIC_FABRIC_SCR_RSP,
|
||||
FNIC_FABRIC_GPN_FT_RSP,
|
||||
FNIC_FABRIC_BLS_ABTS_RSP,
|
||||
FNIC_FDMI_PLOGI_RSP,
|
||||
FNIC_FDMI_REG_HBA_RSP,
|
||||
FNIC_FDMI_RPA_RSP,
|
||||
FNIC_FDMI_BLS_ABTS_RSP,
|
||||
FNIC_FABRIC_LOGO_RSP,
|
||||
|
||||
/* responses to target requests */
|
||||
FNIC_TPORT_PLOGI_RSP,
|
||||
FNIC_TPORT_PRLI_RSP,
|
||||
FNIC_TPORT_ADISC_RSP,
|
||||
FNIC_TPORT_BLS_ABTS_RSP,
|
||||
FNIC_TPORT_LOGO_RSP,
|
||||
|
||||
/* unsolicited requests */
|
||||
FNIC_BLS_ABTS_REQ,
|
||||
FNIC_ELS_PLOGI_REQ,
|
||||
FNIC_ELS_RSCN_REQ,
|
||||
FNIC_ELS_LOGO_REQ,
|
||||
FNIC_ELS_ECHO_REQ,
|
||||
FNIC_ELS_ADISC,
|
||||
FNIC_ELS_RLS,
|
||||
FNIC_ELS_RRQ,
|
||||
FNIC_ELS_UNSUPPORTED_REQ,
|
||||
};
|
||||
|
||||
enum fnic_port_speeds {
|
||||
DCEM_PORTSPEED_NONE = 0,
|
||||
DCEM_PORTSPEED_1G = 1000,
|
||||
DCEM_PORTSPEED_2G = 2000,
|
||||
DCEM_PORTSPEED_4G = 4000,
|
||||
DCEM_PORTSPEED_8G = 8000,
|
||||
DCEM_PORTSPEED_10G = 10000,
|
||||
DCEM_PORTSPEED_16G = 16000,
|
||||
DCEM_PORTSPEED_20G = 20000,
|
||||
DCEM_PORTSPEED_25G = 25000,
|
||||
DCEM_PORTSPEED_32G = 32000,
|
||||
DCEM_PORTSPEED_40G = 40000,
|
||||
DCEM_PORTSPEED_4x10G = 41000,
|
||||
DCEM_PORTSPEED_50G = 50000,
|
||||
DCEM_PORTSPEED_64G = 64000,
|
||||
DCEM_PORTSPEED_100G = 100000,
|
||||
DCEM_PORTSPEED_128G = 128000,
|
||||
};
|
||||
|
||||
/* Function Declarations */
|
||||
/* fdls_disc.c */
|
||||
void fnic_fdls_disc_init(struct fnic_iport_s *iport);
|
||||
void fnic_fdls_disc_start(struct fnic_iport_s *iport);
|
||||
void fnic_fdls_recv_frame(struct fnic_iport_s *iport, void *rx_frame,
|
||||
int len, int fchdr_offset);
|
||||
void fnic_fdls_link_down(struct fnic_iport_s *iport);
|
||||
int fdls_init_frame_pool(struct fnic_iport_s *iport);
|
||||
uint8_t *fdls_alloc_frame(struct fnic_iport_s *iport);
|
||||
uint16_t fdls_alloc_oxid(struct fnic_iport_s *iport, int oxid_frame_type,
|
||||
uint16_t *active_oxid);
|
||||
void fdls_free_oxid(struct fnic_iport_s *iport,
|
||||
uint16_t oxid, uint16_t *active_oxid);
|
||||
void fdls_tgt_logout(struct fnic_iport_s *iport,
|
||||
struct fnic_tport_s *tport);
|
||||
void fnic_del_fabric_timer_sync(struct fnic *fnic);
|
||||
void fnic_del_tport_timer_sync(struct fnic *fnic,
|
||||
struct fnic_tport_s *tport);
|
||||
void fdls_send_fabric_logo(struct fnic_iport_s *iport);
|
||||
int fnic_fdls_validate_and_get_frame_type(struct fnic_iport_s *iport,
|
||||
struct fc_frame_header *fchdr);
|
||||
void fdls_send_tport_abts(struct fnic_iport_s *iport,
|
||||
struct fnic_tport_s *tport);
|
||||
bool fdls_delete_tport(struct fnic_iport_s *iport,
|
||||
struct fnic_tport_s *tport);
|
||||
void fdls_fdmi_timer_callback(struct timer_list *t);
|
||||
|
||||
/* fnic_fcs.c */
|
||||
void fnic_fdls_init(struct fnic *fnic, int usefip);
|
||||
void fnic_send_fcoe_frame(struct fnic_iport_s *iport, void *frame,
|
||||
int frame_size);
|
||||
void fnic_fcoe_send_vlan_req(struct fnic *fnic);
|
||||
int fnic_send_fip_frame(struct fnic_iport_s *iport,
|
||||
void *frame, int frame_size);
|
||||
void fnic_fdls_learn_fcoe_macs(struct fnic_iport_s *iport, void *rx_frame,
|
||||
uint8_t *fcid);
|
||||
void fnic_fdls_add_tport(struct fnic_iport_s *iport,
|
||||
struct fnic_tport_s *tport, unsigned long flags);
|
||||
void fnic_fdls_remove_tport(struct fnic_iport_s *iport,
|
||||
struct fnic_tport_s *tport,
|
||||
unsigned long flags);
|
||||
|
||||
/* fip.c */
|
||||
void fnic_fcoe_send_vlan_req(struct fnic *fnic);
|
||||
void fnic_common_fip_cleanup(struct fnic *fnic);
|
||||
int fdls_fip_recv_frame(struct fnic *fnic, void *frame);
|
||||
void fnic_handle_fcs_ka_timer(struct timer_list *t);
|
||||
void fnic_handle_enode_ka_timer(struct timer_list *t);
|
||||
void fnic_handle_vn_ka_timer(struct timer_list *t);
|
||||
void fnic_handle_fip_timer(struct timer_list *t);
|
||||
extern void fdls_fabric_timer_callback(struct timer_list *t);
|
||||
|
||||
/* fnic_scsi.c */
|
||||
void fnic_scsi_fcpio_reset(struct fnic *fnic);
|
||||
extern void fdls_fabric_timer_callback(struct timer_list *t);
|
||||
void fnic_rport_exch_reset(struct fnic *fnic, u32 fcid);
|
||||
int fnic_fdls_register_portid(struct fnic_iport_s *iport, u32 port_id,
|
||||
void *fp);
|
||||
struct fnic_tport_s *fnic_find_tport_by_fcid(struct fnic_iport_s *iport,
|
||||
uint32_t fcid);
|
||||
struct fnic_tport_s *fnic_find_tport_by_wwpn(struct fnic_iport_s *iport,
|
||||
uint64_t wwpn);
|
||||
|
||||
#endif /* _FNIC_FDLS_H_ */
|
|
@ -1,48 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright 2008 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _FNIC_FIP_H_
|
||||
#define _FNIC_FIP_H_
|
||||
|
||||
|
||||
#define FCOE_CTLR_START_DELAY 2000 /* ms after first adv. to choose FCF */
|
||||
#define FCOE_CTLR_FIPVLAN_TOV 2000 /* ms after FIP VLAN disc */
|
||||
#define FCOE_CTLR_MAX_SOL 8
|
||||
|
||||
#define FINC_MAX_FLOGI_REJECTS 8
|
||||
|
||||
struct vlan {
|
||||
__be16 vid;
|
||||
__be16 type;
|
||||
};
|
||||
|
||||
/*
|
||||
* VLAN entry.
|
||||
*/
|
||||
struct fcoe_vlan {
|
||||
struct list_head list;
|
||||
u16 vid; /* vlan ID */
|
||||
u16 sol_count; /* no. of sols sent */
|
||||
u16 state; /* state */
|
||||
};
|
||||
|
||||
enum fip_vlan_state {
|
||||
FIP_VLAN_AVAIL = 0, /* don't do anything */
|
||||
FIP_VLAN_SENT = 1, /* sent */
|
||||
FIP_VLAN_USED = 2, /* succeed */
|
||||
FIP_VLAN_FAILED = 3, /* failed to response */
|
||||
};
|
||||
|
||||
struct fip_vlan {
|
||||
struct ethhdr eth;
|
||||
struct fip_header fip;
|
||||
struct {
|
||||
struct fip_mac_desc mac;
|
||||
struct fip_wwn_desc wwnn;
|
||||
} desc;
|
||||
};
|
||||
|
||||
#endif /* __FINC_FIP_H_ */
|
|
@ -7,6 +7,7 @@
|
|||
#define _FNIC_IO_H_
|
||||
|
||||
#include <scsi/fc/fc_fcp.h>
|
||||
#include "fnic_fdls.h"
|
||||
|
||||
#define FNIC_DFLT_SG_DESC_CNT 32
|
||||
#define FNIC_MAX_SG_DESC_CNT 256 /* Maximum descriptors per sgl */
|
||||
|
@ -41,6 +42,8 @@ enum fnic_ioreq_state {
|
|||
};
|
||||
|
||||
struct fnic_io_req {
|
||||
struct fnic_iport_s *iport;
|
||||
struct fnic_tport_s *tport;
|
||||
struct host_sg_desc *sgl_list; /* sgl list */
|
||||
void *sgl_list_alloc; /* sgl list address used for free */
|
||||
dma_addr_t sense_buf_pa; /* dma address for sense buffer*/
|
||||
|
@ -55,15 +58,4 @@ struct fnic_io_req {
|
|||
unsigned int tag;
|
||||
struct scsi_cmnd *sc; /* midlayer's cmd pointer */
|
||||
};
|
||||
|
||||
enum fnic_port_speeds {
|
||||
DCEM_PORTSPEED_NONE = 0,
|
||||
DCEM_PORTSPEED_1G = 1000,
|
||||
DCEM_PORTSPEED_10G = 10000,
|
||||
DCEM_PORTSPEED_20G = 20000,
|
||||
DCEM_PORTSPEED_25G = 25000,
|
||||
DCEM_PORTSPEED_40G = 40000,
|
||||
DCEM_PORTSPEED_4x10G = 41000,
|
||||
DCEM_PORTSPEED_100G = 100000,
|
||||
};
|
||||
#endif /* _FNIC_IO_H_ */
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include <linux/errno.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <scsi/libfc.h>
|
||||
#include <scsi/scsi_transport_fc.h>
|
||||
#include <scsi/fc_frame.h>
|
||||
#include "vnic_dev.h"
|
||||
#include "vnic_intr.h"
|
||||
|
@ -222,7 +222,7 @@ int fnic_request_intr(struct fnic *fnic)
|
|||
fnic->msix[i].devname,
|
||||
fnic->msix[i].devid);
|
||||
if (err) {
|
||||
FNIC_ISR_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
|
||||
FNIC_ISR_DBG(KERN_ERR, fnic->host, fnic->fnic_num,
|
||||
"request_irq failed with error: %d\n",
|
||||
err);
|
||||
fnic_free_intr(fnic);
|
||||
|
@ -250,10 +250,10 @@ int fnic_set_intr_mode_msix(struct fnic *fnic)
|
|||
* We need n RQs, m WQs, o Copy WQs, n+m+o CQs, and n+m+o+1 INTRs
|
||||
* (last INTR is used for WQ/RQ errors and notification area)
|
||||
*/
|
||||
FNIC_ISR_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
|
||||
FNIC_ISR_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
|
||||
"rq-array size: %d wq-array size: %d copy-wq array size: %d\n",
|
||||
n, m, o);
|
||||
FNIC_ISR_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
|
||||
FNIC_ISR_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
|
||||
"rq_count: %d raw_wq_count: %d wq_copy_count: %d cq_count: %d\n",
|
||||
fnic->rq_count, fnic->raw_wq_count,
|
||||
fnic->wq_copy_count, fnic->cq_count);
|
||||
|
@ -265,17 +265,17 @@ int fnic_set_intr_mode_msix(struct fnic *fnic)
|
|||
|
||||
vec_count = pci_alloc_irq_vectors(fnic->pdev, min_irqs, vecs,
|
||||
PCI_IRQ_MSIX | PCI_IRQ_AFFINITY);
|
||||
FNIC_ISR_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
|
||||
FNIC_ISR_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
|
||||
"allocated %d MSI-X vectors\n",
|
||||
vec_count);
|
||||
|
||||
if (vec_count > 0) {
|
||||
if (vec_count < vecs) {
|
||||
FNIC_ISR_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
|
||||
FNIC_ISR_DBG(KERN_ERR, fnic->host, fnic->fnic_num,
|
||||
"interrupts number mismatch: vec_count: %d vecs: %d\n",
|
||||
vec_count, vecs);
|
||||
if (vec_count < min_irqs) {
|
||||
FNIC_ISR_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
|
||||
FNIC_ISR_DBG(KERN_ERR, fnic->host, fnic->fnic_num,
|
||||
"no interrupts for copy wq\n");
|
||||
return 1;
|
||||
}
|
||||
|
@ -287,7 +287,7 @@ int fnic_set_intr_mode_msix(struct fnic *fnic)
|
|||
fnic->wq_copy_count = vec_count - n - m - 1;
|
||||
fnic->wq_count = fnic->raw_wq_count + fnic->wq_copy_count;
|
||||
if (fnic->cq_count != vec_count - 1) {
|
||||
FNIC_ISR_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
|
||||
FNIC_ISR_DBG(KERN_ERR, fnic->host, fnic->fnic_num,
|
||||
"CQ count: %d does not match MSI-X vector count: %d\n",
|
||||
fnic->cq_count, vec_count);
|
||||
fnic->cq_count = vec_count - 1;
|
||||
|
@ -295,23 +295,23 @@ int fnic_set_intr_mode_msix(struct fnic *fnic)
|
|||
fnic->intr_count = vec_count;
|
||||
fnic->err_intr_offset = fnic->rq_count + fnic->wq_count;
|
||||
|
||||
FNIC_ISR_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
|
||||
FNIC_ISR_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
|
||||
"rq_count: %d raw_wq_count: %d copy_wq_base: %d\n",
|
||||
fnic->rq_count,
|
||||
fnic->raw_wq_count, fnic->copy_wq_base);
|
||||
|
||||
FNIC_ISR_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
|
||||
FNIC_ISR_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
|
||||
"wq_copy_count: %d wq_count: %d cq_count: %d\n",
|
||||
fnic->wq_copy_count,
|
||||
fnic->wq_count, fnic->cq_count);
|
||||
|
||||
FNIC_ISR_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
|
||||
FNIC_ISR_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
|
||||
"intr_count: %d err_intr_offset: %u",
|
||||
fnic->intr_count,
|
||||
fnic->err_intr_offset);
|
||||
|
||||
vnic_dev_set_intr_mode(fnic->vdev, VNIC_DEV_INTR_MODE_MSIX);
|
||||
FNIC_ISR_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
|
||||
FNIC_ISR_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
|
||||
"fnic using MSI-X\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -351,7 +351,7 @@ int fnic_set_intr_mode(struct fnic *fnic)
|
|||
fnic->intr_count = 1;
|
||||
fnic->err_intr_offset = 0;
|
||||
|
||||
FNIC_ISR_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
|
||||
FNIC_ISR_DBG(KERN_DEBUG, fnic->host, fnic->fnic_num,
|
||||
"Using MSI Interrupts\n");
|
||||
vnic_dev_set_intr_mode(fnic->vdev, VNIC_DEV_INTR_MODE_MSI);
|
||||
|
||||
|
@ -377,7 +377,7 @@ int fnic_set_intr_mode(struct fnic *fnic)
|
|||
fnic->cq_count = 3;
|
||||
fnic->intr_count = 3;
|
||||
|
||||
FNIC_ISR_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
|
||||
FNIC_ISR_DBG(KERN_DEBUG, fnic->host, fnic->fnic_num,
|
||||
"Using Legacy Interrupts\n");
|
||||
vnic_dev_set_intr_mode(fnic->vdev, VNIC_DEV_INTR_MODE_INTX);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
131
drivers/scsi/fnic/fnic_pci_subsys_devid.c
Normal file
131
drivers/scsi/fnic/fnic_pci_subsys_devid.c
Normal file
|
@ -0,0 +1,131 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright 2008 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright 2007 Nuova Systems, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/mempool.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include "fnic.h"
|
||||
|
||||
static struct fnic_pcie_device fnic_pcie_device_table[] = {
|
||||
{PCI_DEVICE_ID_CISCO_SERENO, "Sereno", PCI_SUBDEVICE_ID_CISCO_VASONA,
|
||||
"VIC 1280"},
|
||||
{PCI_DEVICE_ID_CISCO_SERENO, "Sereno", PCI_SUBDEVICE_ID_CISCO_COTATI,
|
||||
"VIC 1240"},
|
||||
{PCI_DEVICE_ID_CISCO_SERENO, "Sereno",
|
||||
PCI_SUBDEVICE_ID_CISCO_LEXINGTON, "VIC 1225"},
|
||||
{PCI_DEVICE_ID_CISCO_SERENO, "Sereno", PCI_SUBDEVICE_ID_CISCO_ICEHOUSE,
|
||||
"VIC 1285"},
|
||||
{PCI_DEVICE_ID_CISCO_SERENO, "Sereno",
|
||||
PCI_SUBDEVICE_ID_CISCO_KIRKWOODLAKE, "VIC 1225T"},
|
||||
{PCI_DEVICE_ID_CISCO_SERENO, "Sereno",
|
||||
PCI_SUBDEVICE_ID_CISCO_SUSANVILLE, "VIC 1227"},
|
||||
{PCI_DEVICE_ID_CISCO_SERENO, "Sereno", PCI_SUBDEVICE_ID_CISCO_TORRANCE,
|
||||
"VIC 1227T"},
|
||||
|
||||
{PCI_DEVICE_ID_CISCO_CRUZ, "Cruz", PCI_SUBDEVICE_ID_CISCO_CALISTOGA,
|
||||
"VIC 1340"},
|
||||
{PCI_DEVICE_ID_CISCO_CRUZ, "Cruz", PCI_SUBDEVICE_ID_CISCO_MOUNTAINVIEW,
|
||||
"VIC 1380"},
|
||||
{PCI_DEVICE_ID_CISCO_CRUZ, "Cruz", PCI_SUBDEVICE_ID_CISCO_MOUNTTIAN,
|
||||
"C3260-SIOC"},
|
||||
{PCI_DEVICE_ID_CISCO_CRUZ, "Cruz", PCI_SUBDEVICE_ID_CISCO_CLEARLAKE,
|
||||
"VIC 1385"},
|
||||
{PCI_DEVICE_ID_CISCO_CRUZ, "Cruz", PCI_SUBDEVICE_ID_CISCO_MOUNTTIAN2,
|
||||
"C3260-SIOC"},
|
||||
{PCI_DEVICE_ID_CISCO_CRUZ, "Cruz", PCI_SUBDEVICE_ID_CISCO_CLAREMONT,
|
||||
"VIC 1387"},
|
||||
|
||||
{PCI_DEVICE_ID_CISCO_BODEGA, "Bodega", PCI_SUBDEVICE_ID_CISCO_BRADBURY,
|
||||
"VIC 1457"},
|
||||
{PCI_DEVICE_ID_CISCO_BODEGA, "Bodega",
|
||||
PCI_SUBDEVICE_ID_CISCO_BRENTWOOD, "VIC 1455"},
|
||||
{PCI_DEVICE_ID_CISCO_BODEGA, "Bodega",
|
||||
PCI_SUBDEVICE_ID_CISCO_BURLINGAME, "VIC 1487"},
|
||||
{PCI_DEVICE_ID_CISCO_BODEGA, "Bodega", PCI_SUBDEVICE_ID_CISCO_BAYSIDE,
|
||||
"VIC 1485"},
|
||||
{PCI_DEVICE_ID_CISCO_BODEGA, "Bodega",
|
||||
PCI_SUBDEVICE_ID_CISCO_BAKERSFIELD, "VIC 1440"},
|
||||
{PCI_DEVICE_ID_CISCO_BODEGA, "Bodega",
|
||||
PCI_SUBDEVICE_ID_CISCO_BOONVILLE, "VIC 1480"},
|
||||
{PCI_DEVICE_ID_CISCO_BODEGA, "Bodega", PCI_SUBDEVICE_ID_CISCO_BENICIA,
|
||||
"VIC 1495"},
|
||||
{PCI_DEVICE_ID_CISCO_BODEGA, "Bodega", PCI_SUBDEVICE_ID_CISCO_BEAUMONT,
|
||||
"VIC 1497"},
|
||||
{PCI_DEVICE_ID_CISCO_BODEGA, "Bodega", PCI_SUBDEVICE_ID_CISCO_BRISBANE,
|
||||
"VIC 1467"},
|
||||
{PCI_DEVICE_ID_CISCO_BODEGA, "Bodega", PCI_SUBDEVICE_ID_CISCO_BENTON,
|
||||
"VIC 1477"},
|
||||
{PCI_DEVICE_ID_CISCO_BODEGA, "Bodega",
|
||||
PCI_SUBDEVICE_ID_CISCO_TWIN_RIVER, "VIC 14425"},
|
||||
{PCI_DEVICE_ID_CISCO_BODEGA, "Bodega",
|
||||
PCI_SUBDEVICE_ID_CISCO_TWIN_PEAK, "VIC 14825"},
|
||||
|
||||
{PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly", PCI_SUBDEVICE_ID_CISCO_BERN,
|
||||
"VIC 15420"},
|
||||
{PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly",
|
||||
PCI_SUBDEVICE_ID_CISCO_STOCKHOLM, "VIC 15428"},
|
||||
{PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly", PCI_SUBDEVICE_ID_CISCO_KRAKOW,
|
||||
"VIC 15411"},
|
||||
{PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly",
|
||||
PCI_SUBDEVICE_ID_CISCO_LUCERNE, "VIC 15231"},
|
||||
{PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly", PCI_SUBDEVICE_ID_CISCO_TURKU,
|
||||
"VIC 15238"},
|
||||
{PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly", PCI_SUBDEVICE_ID_CISCO_GENEVA,
|
||||
"VIC 15422"},
|
||||
{PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly",
|
||||
PCI_SUBDEVICE_ID_CISCO_HELSINKI, "VIC 15235"},
|
||||
{PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly",
|
||||
PCI_SUBDEVICE_ID_CISCO_GOTHENBURG, "VIC 15425"},
|
||||
{PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly",
|
||||
PCI_SUBDEVICE_ID_CISCO_TURKU_PLUS, "VIC 15237"},
|
||||
{PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly", PCI_SUBDEVICE_ID_CISCO_ZURICH,
|
||||
"VIC 15230"},
|
||||
{PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly", PCI_SUBDEVICE_ID_CISCO_RIGA,
|
||||
"VIC 15427"},
|
||||
|
||||
{0,}
|
||||
};
|
||||
|
||||
int fnic_get_desc_by_devid(struct pci_dev *pdev, char **desc,
|
||||
char **subsys_desc)
|
||||
{
|
||||
unsigned short device = PCI_DEVICE_ID_CISCO_VIC_FC;
|
||||
int max = ARRAY_SIZE(fnic_pcie_device_table);
|
||||
struct fnic_pcie_device *t = fnic_pcie_device_table;
|
||||
int index = 0;
|
||||
|
||||
if (pdev->device != device)
|
||||
return 1;
|
||||
|
||||
while (t->device != 0) {
|
||||
if (memcmp
|
||||
((char *) &pdev->subsystem_device,
|
||||
(char *) &t->subsystem_device, sizeof(short)) == 0)
|
||||
break;
|
||||
t++;
|
||||
index++;
|
||||
}
|
||||
|
||||
if (index >= max - 1) {
|
||||
*desc = NULL;
|
||||
*subsys_desc = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
*desc = fnic_pcie_device_table[index].desc;
|
||||
*subsys_desc = fnic_pcie_device_table[index].subsys_desc;
|
||||
return 0;
|
||||
}
|
|
@ -30,9 +30,7 @@ int fnic_get_vnic_config(struct fnic *fnic)
|
|||
offsetof(struct vnic_fc_config, m), \
|
||||
sizeof(c->m), &c->m); \
|
||||
if (err) { \
|
||||
shost_printk(KERN_ERR, fnic->lport->host, \
|
||||
"Error getting %s, %d\n", #m, \
|
||||
err); \
|
||||
dev_err(&fnic->pdev->dev, "Error getting %s, %d\n", #m, err); \
|
||||
return err; \
|
||||
} \
|
||||
} while (0);
|
||||
|
@ -60,6 +58,11 @@ int fnic_get_vnic_config(struct fnic *fnic)
|
|||
GET_CONFIG(intr_mode);
|
||||
GET_CONFIG(wq_copy_count);
|
||||
|
||||
if ((c->flags & (VFCF_FC_INITIATOR)) == 0) {
|
||||
dev_info(&fnic->pdev->dev, "vNIC role not defined (def role: FC Init)\n");
|
||||
c->flags |= VFCF_FC_INITIATOR;
|
||||
}
|
||||
|
||||
c->wq_enet_desc_count =
|
||||
min_t(u32, VNIC_FNIC_WQ_DESCS_MAX,
|
||||
max_t(u32, VNIC_FNIC_WQ_DESCS_MIN,
|
||||
|
@ -139,40 +142,28 @@ int fnic_get_vnic_config(struct fnic *fnic)
|
|||
|
||||
c->wq_copy_count = min_t(u16, FNIC_WQ_COPY_MAX, c->wq_copy_count);
|
||||
|
||||
shost_printk(KERN_INFO, fnic->lport->host,
|
||||
"vNIC MAC addr %pM "
|
||||
"wq/wq_copy/rq %d/%d/%d\n",
|
||||
fnic->ctlr.ctl_src_addr,
|
||||
dev_info(&fnic->pdev->dev, "fNIC MAC addr %p wq/wq_copy/rq %d/%d/%d\n",
|
||||
fnic->data_src_addr,
|
||||
c->wq_enet_desc_count, c->wq_copy_desc_count,
|
||||
c->rq_desc_count);
|
||||
shost_printk(KERN_INFO, fnic->lport->host,
|
||||
"vNIC node wwn %llx port wwn %llx\n",
|
||||
dev_info(&fnic->pdev->dev, "fNIC node wwn 0x%llx port wwn 0x%llx\n",
|
||||
c->node_wwn, c->port_wwn);
|
||||
shost_printk(KERN_INFO, fnic->lport->host,
|
||||
"vNIC ed_tov %d ra_tov %d\n",
|
||||
dev_info(&fnic->pdev->dev, "fNIC ed_tov %d ra_tov %d\n",
|
||||
c->ed_tov, c->ra_tov);
|
||||
shost_printk(KERN_INFO, fnic->lport->host,
|
||||
"vNIC mtu %d intr timer %d\n",
|
||||
dev_info(&fnic->pdev->dev, "fNIC mtu %d intr timer %d\n",
|
||||
c->maxdatafieldsize, c->intr_timer);
|
||||
shost_printk(KERN_INFO, fnic->lport->host,
|
||||
"vNIC flags 0x%x luns per tgt %d\n",
|
||||
dev_info(&fnic->pdev->dev, "fNIC flags 0x%x luns per tgt %d\n",
|
||||
c->flags, c->luns_per_tgt);
|
||||
shost_printk(KERN_INFO, fnic->lport->host,
|
||||
"vNIC flogi_retries %d flogi timeout %d\n",
|
||||
dev_info(&fnic->pdev->dev, "fNIC flogi_retries %d flogi timeout %d\n",
|
||||
c->flogi_retries, c->flogi_timeout);
|
||||
shost_printk(KERN_INFO, fnic->lport->host,
|
||||
"vNIC plogi retries %d plogi timeout %d\n",
|
||||
dev_info(&fnic->pdev->dev, "fNIC plogi retries %d plogi timeout %d\n",
|
||||
c->plogi_retries, c->plogi_timeout);
|
||||
shost_printk(KERN_INFO, fnic->lport->host,
|
||||
"vNIC io throttle count %d link dn timeout %d\n",
|
||||
dev_info(&fnic->pdev->dev, "fNIC io throttle count %d link dn timeout %d\n",
|
||||
c->io_throttle_count, c->link_down_timeout);
|
||||
shost_printk(KERN_INFO, fnic->lport->host,
|
||||
"vNIC port dn io retries %d port dn timeout %d\n",
|
||||
dev_info(&fnic->pdev->dev, "fNIC port dn io retries %d port dn timeout %d\n",
|
||||
c->port_down_io_retries, c->port_down_timeout);
|
||||
shost_printk(KERN_INFO, fnic->lport->host,
|
||||
"vNIC wq_copy_count: %d\n", c->wq_copy_count);
|
||||
shost_printk(KERN_INFO, fnic->lport->host,
|
||||
"vNIC intr mode: %d\n", c->intr_mode);
|
||||
dev_info(&fnic->pdev->dev, "fNIC wq_copy_count: %d\n", c->wq_copy_count);
|
||||
dev_info(&fnic->pdev->dev, "fNIC intr mode: %d\n", c->intr_mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -206,18 +197,12 @@ void fnic_get_res_counts(struct fnic *fnic)
|
|||
fnic->intr_count = vnic_dev_get_res_count(fnic->vdev,
|
||||
RES_TYPE_INTR_CTRL);
|
||||
|
||||
shost_printk(KERN_INFO, fnic->lport->host,
|
||||
"vNIC fw resources wq_count: %d\n", fnic->wq_count);
|
||||
shost_printk(KERN_INFO, fnic->lport->host,
|
||||
"vNIC fw resources raw_wq_count: %d\n", fnic->raw_wq_count);
|
||||
shost_printk(KERN_INFO, fnic->lport->host,
|
||||
"vNIC fw resources wq_copy_count: %d\n", fnic->wq_copy_count);
|
||||
shost_printk(KERN_INFO, fnic->lport->host,
|
||||
"vNIC fw resources rq_count: %d\n", fnic->rq_count);
|
||||
shost_printk(KERN_INFO, fnic->lport->host,
|
||||
"vNIC fw resources cq_count: %d\n", fnic->cq_count);
|
||||
shost_printk(KERN_INFO, fnic->lport->host,
|
||||
"vNIC fw resources intr_count: %d\n", fnic->intr_count);
|
||||
dev_info(&fnic->pdev->dev, "vNIC fw resources wq_count: %d\n", fnic->wq_count);
|
||||
dev_info(&fnic->pdev->dev, "vNIC fw resources raw_wq_count: %d\n", fnic->raw_wq_count);
|
||||
dev_info(&fnic->pdev->dev, "vNIC fw resources wq_copy_count: %d\n", fnic->wq_copy_count);
|
||||
dev_info(&fnic->pdev->dev, "vNIC fw resources rq_count: %d\n", fnic->rq_count);
|
||||
dev_info(&fnic->pdev->dev, "vNIC fw resources cq_count: %d\n", fnic->cq_count);
|
||||
dev_info(&fnic->pdev->dev, "vNIC fw resources intr_count: %d\n", fnic->intr_count);
|
||||
}
|
||||
|
||||
void fnic_free_vnic_resources(struct fnic *fnic)
|
||||
|
@ -253,19 +238,17 @@ int fnic_alloc_vnic_resources(struct fnic *fnic)
|
|||
|
||||
intr_mode = vnic_dev_get_intr_mode(fnic->vdev);
|
||||
|
||||
shost_printk(KERN_INFO, fnic->lport->host, "vNIC interrupt mode: %s\n",
|
||||
dev_info(&fnic->pdev->dev, "vNIC interrupt mode: %s\n",
|
||||
intr_mode == VNIC_DEV_INTR_MODE_INTX ? "legacy PCI INTx" :
|
||||
intr_mode == VNIC_DEV_INTR_MODE_MSI ? "MSI" :
|
||||
intr_mode == VNIC_DEV_INTR_MODE_MSIX ?
|
||||
"MSI-X" : "unknown");
|
||||
|
||||
shost_printk(KERN_INFO, fnic->lport->host,
|
||||
"vNIC resources avail: wq %d cp_wq %d raw_wq %d rq %d",
|
||||
dev_info(&fnic->pdev->dev, "res avail: wq %d cp_wq %d raw_wq %d rq %d",
|
||||
fnic->wq_count, fnic->wq_copy_count,
|
||||
fnic->raw_wq_count, fnic->rq_count);
|
||||
|
||||
shost_printk(KERN_INFO, fnic->lport->host,
|
||||
"vNIC resources avail: cq %d intr %d cpy-wq desc count %d\n",
|
||||
dev_info(&fnic->pdev->dev, "res avail: cq %d intr %d cpy-wq desc count %d\n",
|
||||
fnic->cq_count, fnic->intr_count,
|
||||
fnic->config.wq_copy_desc_count);
|
||||
|
||||
|
@ -340,8 +323,7 @@ int fnic_alloc_vnic_resources(struct fnic *fnic)
|
|||
RES_TYPE_INTR_PBA_LEGACY, 0);
|
||||
|
||||
if (!fnic->legacy_pba && intr_mode == VNIC_DEV_INTR_MODE_INTX) {
|
||||
shost_printk(KERN_ERR, fnic->lport->host,
|
||||
"Failed to hook legacy pba resource\n");
|
||||
dev_err(&fnic->pdev->dev, "Failed to hook legacy pba resource\n");
|
||||
err = -ENODEV;
|
||||
goto err_out_cleanup;
|
||||
}
|
||||
|
@ -444,8 +426,7 @@ int fnic_alloc_vnic_resources(struct fnic *fnic)
|
|||
/* init the stats memory by making the first call here */
|
||||
err = vnic_dev_stats_dump(fnic->vdev, &fnic->stats);
|
||||
if (err) {
|
||||
shost_printk(KERN_ERR, fnic->lport->host,
|
||||
"vnic_dev_stats_dump failed - x%x\n", err);
|
||||
dev_err(&fnic->pdev->dev, "vnic_dev_stats_dump failed - x%x\n", err);
|
||||
goto err_out_cleanup;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,6 +3,7 @@
|
|||
#ifndef _FNIC_STATS_H_
|
||||
#define _FNIC_STATS_H_
|
||||
#define FNIC_MQ_MAX_QUEUES 64
|
||||
#include <scsi/scsi_transport_fc.h>
|
||||
|
||||
struct stats_timestamps {
|
||||
struct timespec64 last_reset_time;
|
||||
|
@ -63,6 +64,7 @@ struct reset_stats {
|
|||
atomic64_t fw_resets;
|
||||
atomic64_t fw_reset_completions;
|
||||
atomic64_t fw_reset_failures;
|
||||
atomic64_t fw_reset_timeouts;
|
||||
atomic64_t fnic_resets;
|
||||
atomic64_t fnic_reset_completions;
|
||||
atomic64_t fnic_reset_failures;
|
||||
|
@ -102,10 +104,51 @@ struct misc_stats {
|
|||
atomic64_t no_icmnd_itmf_cmpls;
|
||||
atomic64_t check_condition;
|
||||
atomic64_t queue_fulls;
|
||||
atomic64_t rport_not_ready;
|
||||
atomic64_t tport_not_ready;
|
||||
atomic64_t iport_not_ready;
|
||||
atomic64_t frame_errors;
|
||||
atomic64_t current_port_speed;
|
||||
atomic64_t intx_dummy;
|
||||
atomic64_t port_speed_in_mbps;
|
||||
};
|
||||
|
||||
struct fnic_iport_stats {
|
||||
atomic64_t num_linkdn;
|
||||
atomic64_t num_linkup;
|
||||
atomic64_t link_failure_count;
|
||||
atomic64_t num_rscns;
|
||||
atomic64_t rscn_redisc;
|
||||
atomic64_t rscn_not_redisc;
|
||||
atomic64_t frame_err;
|
||||
atomic64_t num_rnid;
|
||||
atomic64_t fabric_flogi_sent;
|
||||
atomic64_t fabric_flogi_ls_accepts;
|
||||
atomic64_t fabric_flogi_ls_rejects;
|
||||
atomic64_t fabric_flogi_misc_rejects;
|
||||
atomic64_t fabric_plogi_sent;
|
||||
atomic64_t fabric_plogi_ls_accepts;
|
||||
atomic64_t fabric_plogi_ls_rejects;
|
||||
atomic64_t fabric_plogi_misc_rejects;
|
||||
atomic64_t fabric_scr_sent;
|
||||
atomic64_t fabric_scr_ls_accepts;
|
||||
atomic64_t fabric_scr_ls_rejects;
|
||||
atomic64_t fabric_scr_misc_rejects;
|
||||
atomic64_t fabric_logo_sent;
|
||||
atomic64_t tport_alive;
|
||||
atomic64_t tport_plogi_sent;
|
||||
atomic64_t tport_plogi_ls_accepts;
|
||||
atomic64_t tport_plogi_ls_rejects;
|
||||
atomic64_t tport_plogi_misc_rejects;
|
||||
atomic64_t tport_prli_sent;
|
||||
atomic64_t tport_prli_ls_accepts;
|
||||
atomic64_t tport_prli_ls_rejects;
|
||||
atomic64_t tport_prli_misc_rejects;
|
||||
atomic64_t tport_adisc_sent;
|
||||
atomic64_t tport_adisc_ls_accepts;
|
||||
atomic64_t tport_adisc_ls_rejects;
|
||||
atomic64_t tport_logo_sent;
|
||||
atomic64_t unsupported_frames_ls_rejects;
|
||||
atomic64_t unsupported_frames_dropped;
|
||||
};
|
||||
|
||||
struct fnic_stats {
|
||||
|
@ -116,6 +159,7 @@ struct fnic_stats {
|
|||
struct reset_stats reset_stats;
|
||||
struct fw_stats fw_stats;
|
||||
struct vlan_stats vlan_stats;
|
||||
struct fc_host_statistics host_stats;
|
||||
struct misc_stats misc_stats;
|
||||
};
|
||||
|
||||
|
@ -127,6 +171,5 @@ struct stats_debug_info {
|
|||
};
|
||||
|
||||
int fnic_get_stats_data(struct stats_debug_info *, struct fnic_stats *);
|
||||
void fnic_stats_debugfs_init(struct fnic *);
|
||||
void fnic_stats_debugfs_remove(struct fnic *);
|
||||
const char *fnic_role_to_str(unsigned int role);
|
||||
#endif /* _FNIC_STATS_H_ */
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <linux/kallsyms.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <scsi/scsi_transport_fc.h>
|
||||
#include "fnic_io.h"
|
||||
#include "fnic.h"
|
||||
|
||||
|
@ -29,6 +30,17 @@ int fnic_fc_tracing_enabled = 1;
|
|||
int fnic_fc_trace_cleared = 1;
|
||||
static DEFINE_SPINLOCK(fnic_fc_trace_lock);
|
||||
|
||||
static const char * const fnic_role_str[] = {
|
||||
[FNIC_ROLE_FCP_INITIATOR] = "FCP_Initiator",
|
||||
};
|
||||
|
||||
const char *fnic_role_to_str(unsigned int role)
|
||||
{
|
||||
if (role >= ARRAY_SIZE(fnic_role_str) || !fnic_role_str[role])
|
||||
return "Unknown";
|
||||
|
||||
return fnic_role_str[role];
|
||||
}
|
||||
|
||||
/*
|
||||
* fnic_trace_get_buf - Give buffer pointer to user to fill up trace information
|
||||
|
@ -423,7 +435,8 @@ int fnic_get_stats_data(struct stats_debug_info *debug,
|
|||
"Number of Check Conditions encountered: %lld\n"
|
||||
"Number of QUEUE Fulls: %lld\n"
|
||||
"Number of rport not ready: %lld\n"
|
||||
"Number of receive frame errors: %lld\n",
|
||||
"Number of receive frame errors: %lld\n"
|
||||
"Port speed (in Mbps): %lld\n",
|
||||
(u64)stats->misc_stats.last_isr_time,
|
||||
(s64)val1.tv_sec, val1.tv_nsec,
|
||||
(u64)stats->misc_stats.last_ack_time,
|
||||
|
@ -446,18 +459,68 @@ int fnic_get_stats_data(struct stats_debug_info *debug,
|
|||
(u64)atomic64_read(&stats->misc_stats.no_icmnd_itmf_cmpls),
|
||||
(u64)atomic64_read(&stats->misc_stats.check_condition),
|
||||
(u64)atomic64_read(&stats->misc_stats.queue_fulls),
|
||||
(u64)atomic64_read(&stats->misc_stats.rport_not_ready),
|
||||
(u64)atomic64_read(&stats->misc_stats.frame_errors));
|
||||
|
||||
len += scnprintf(debug->debug_buffer + len, buf_size - len,
|
||||
"Firmware reported port speed: %llu\n",
|
||||
(u64)atomic64_read(
|
||||
&stats->misc_stats.current_port_speed));
|
||||
(u64)atomic64_read(&stats->misc_stats.tport_not_ready),
|
||||
(u64)atomic64_read(&stats->misc_stats.frame_errors),
|
||||
(u64)atomic64_read(&stats->misc_stats.port_speed_in_mbps));
|
||||
|
||||
return len;
|
||||
|
||||
}
|
||||
|
||||
int fnic_get_debug_info(struct stats_debug_info *info, struct fnic *fnic)
|
||||
{
|
||||
struct fnic_iport_s *iport = &fnic->iport;
|
||||
int buf_size = info->buf_size;
|
||||
int len = info->buffer_len;
|
||||
struct fnic_tport_s *tport, *next;
|
||||
unsigned long flags;
|
||||
|
||||
len += snprintf(info->debug_buffer + len, buf_size - len,
|
||||
"------------------------------------------\n"
|
||||
"\t\t Debug Info\n"
|
||||
"------------------------------------------\n");
|
||||
len += snprintf(info->debug_buffer + len, buf_size - len,
|
||||
"fnic Name:%s number:%d Role:%s State:%s\n",
|
||||
fnic->name, fnic->fnic_num,
|
||||
fnic_role_to_str(fnic->role),
|
||||
fnic_state_to_str(fnic->state));
|
||||
len +=
|
||||
snprintf(info->debug_buffer + len, buf_size - len,
|
||||
"iport State:%d Flags:0x%x vlan_id:%d fcid:0x%x\n",
|
||||
iport->state, iport->flags, iport->vlan_id, iport->fcid);
|
||||
len +=
|
||||
snprintf(info->debug_buffer + len, buf_size - len,
|
||||
"usefip:%d fip_state:%d fip_flogi_retry:%d\n",
|
||||
iport->usefip, iport->fip.state, iport->fip.flogi_retry);
|
||||
len +=
|
||||
snprintf(info->debug_buffer + len, buf_size - len,
|
||||
"fpma %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
iport->fpma[5], iport->fpma[4], iport->fpma[3],
|
||||
iport->fpma[2], iport->fpma[1], iport->fpma[0]);
|
||||
len +=
|
||||
snprintf(info->debug_buffer + len, buf_size - len,
|
||||
"fcfmac %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
iport->fcfmac[5], iport->fcfmac[4], iport->fcfmac[3],
|
||||
iport->fcfmac[2], iport->fcfmac[1], iport->fcfmac[0]);
|
||||
len +=
|
||||
snprintf(info->debug_buffer + len, buf_size - len,
|
||||
"fabric state:%d flags:0x%x retry_counter:%d e_d_tov:%d r_a_tov:%d\n",
|
||||
iport->fabric.state, iport->fabric.flags,
|
||||
iport->fabric.retry_counter, iport->e_d_tov,
|
||||
iport->r_a_tov);
|
||||
|
||||
spin_lock_irqsave(&fnic->fnic_lock, flags);
|
||||
list_for_each_entry_safe(tport, next, &iport->tport_list, links) {
|
||||
len += snprintf(info->debug_buffer + len, buf_size - len,
|
||||
"tport fcid:0x%x state:%d flags:0x%x inflight:%d retry_counter:%d\n",
|
||||
tport->fcid, tport->state, tport->flags,
|
||||
atomic_read(&tport->in_flight),
|
||||
tport->retry_counter);
|
||||
}
|
||||
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* fnic_trace_buf_init - Initialize fnic trace buffer logging facility
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue
Block a user