mirror of https://gitee.com/openkylin/linux.git
[SCSI] bfa: Add FC-transport based Asynchronous Event Notification support.
- Added support to post vendor unique events on fc_host. - Supports adapter, port, ioc, flash and remote port based AEN events. Signed-off-by: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
a53becc9a9
commit
7826f304b1
|
@ -164,6 +164,8 @@ enum bfa_status {
|
|||
BFA_STATUS_INVALID_MAC = 134, /* Invalid MAC address */
|
||||
BFA_STATUS_PBC = 154, /* Operation not allowed for pre-boot
|
||||
* configuration */
|
||||
BFA_STATUS_BAD_FWCFG = 156, /* Bad firmware configuration */
|
||||
BFA_STATUS_INVALID_VENDOR = 158, /* Invalid switch vendor */
|
||||
BFA_STATUS_SFP_NOT_READY = 159, /* SFP info is not ready. Retry */
|
||||
BFA_STATUS_TRUNK_ENABLED = 164, /* Trunk is already enabled on
|
||||
* this adapter */
|
||||
|
@ -358,6 +360,139 @@ struct bfa_ioc_attr_s {
|
|||
u8 rsvd[4]; /* 64bit align */
|
||||
};
|
||||
|
||||
/*
|
||||
* AEN related definitions
|
||||
*/
|
||||
enum bfa_aen_category {
|
||||
BFA_AEN_CAT_ADAPTER = 1,
|
||||
BFA_AEN_CAT_PORT = 2,
|
||||
BFA_AEN_CAT_LPORT = 3,
|
||||
BFA_AEN_CAT_RPORT = 4,
|
||||
BFA_AEN_CAT_ITNIM = 5,
|
||||
BFA_AEN_CAT_AUDIT = 8,
|
||||
BFA_AEN_CAT_IOC = 9,
|
||||
};
|
||||
|
||||
/* BFA adapter level events */
|
||||
enum bfa_adapter_aen_event {
|
||||
BFA_ADAPTER_AEN_ADD = 1, /* New Adapter found event */
|
||||
BFA_ADAPTER_AEN_REMOVE = 2, /* Adapter removed event */
|
||||
};
|
||||
|
||||
struct bfa_adapter_aen_data_s {
|
||||
char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
|
||||
u32 nports; /* Number of NPorts */
|
||||
wwn_t pwwn; /* WWN of one of its physical port */
|
||||
};
|
||||
|
||||
/* BFA physical port Level events */
|
||||
enum bfa_port_aen_event {
|
||||
BFA_PORT_AEN_ONLINE = 1, /* Physical Port online event */
|
||||
BFA_PORT_AEN_OFFLINE = 2, /* Physical Port offline event */
|
||||
BFA_PORT_AEN_RLIR = 3, /* RLIR event, not supported */
|
||||
BFA_PORT_AEN_SFP_INSERT = 4, /* SFP inserted event */
|
||||
BFA_PORT_AEN_SFP_REMOVE = 5, /* SFP removed event */
|
||||
BFA_PORT_AEN_SFP_POM = 6, /* SFP POM event */
|
||||
BFA_PORT_AEN_ENABLE = 7, /* Physical Port enable event */
|
||||
BFA_PORT_AEN_DISABLE = 8, /* Physical Port disable event */
|
||||
BFA_PORT_AEN_AUTH_ON = 9, /* Physical Port auth success event */
|
||||
BFA_PORT_AEN_AUTH_OFF = 10, /* Physical Port auth fail event */
|
||||
BFA_PORT_AEN_DISCONNECT = 11, /* Physical Port disconnect event */
|
||||
BFA_PORT_AEN_QOS_NEG = 12, /* Base Port QOS negotiation event */
|
||||
BFA_PORT_AEN_FABRIC_NAME_CHANGE = 13, /* Fabric Name/WWN change */
|
||||
BFA_PORT_AEN_SFP_ACCESS_ERROR = 14, /* SFP read error event */
|
||||
BFA_PORT_AEN_SFP_UNSUPPORT = 15, /* Unsupported SFP event */
|
||||
};
|
||||
|
||||
enum bfa_port_aen_sfp_pom {
|
||||
BFA_PORT_AEN_SFP_POM_GREEN = 1, /* Normal */
|
||||
BFA_PORT_AEN_SFP_POM_AMBER = 2, /* Warning */
|
||||
BFA_PORT_AEN_SFP_POM_RED = 3, /* Critical */
|
||||
BFA_PORT_AEN_SFP_POM_MAX = BFA_PORT_AEN_SFP_POM_RED
|
||||
};
|
||||
|
||||
struct bfa_port_aen_data_s {
|
||||
wwn_t pwwn; /* WWN of the physical port */
|
||||
wwn_t fwwn; /* WWN of the fabric port */
|
||||
u32 phy_port_num; /* For SFP related events */
|
||||
u16 ioc_type;
|
||||
u16 level; /* Only transitions will be informed */
|
||||
mac_t mac; /* MAC address of the ethernet port */
|
||||
u16 rsvd;
|
||||
};
|
||||
|
||||
/* BFA AEN logical port events */
|
||||
enum bfa_lport_aen_event {
|
||||
BFA_LPORT_AEN_NEW = 1, /* LPort created event */
|
||||
BFA_LPORT_AEN_DELETE = 2, /* LPort deleted event */
|
||||
BFA_LPORT_AEN_ONLINE = 3, /* LPort online event */
|
||||
BFA_LPORT_AEN_OFFLINE = 4, /* LPort offline event */
|
||||
BFA_LPORT_AEN_DISCONNECT = 5, /* LPort disconnect event */
|
||||
BFA_LPORT_AEN_NEW_PROP = 6, /* VPort created event */
|
||||
BFA_LPORT_AEN_DELETE_PROP = 7, /* VPort deleted event */
|
||||
BFA_LPORT_AEN_NEW_STANDARD = 8, /* VPort created event */
|
||||
BFA_LPORT_AEN_DELETE_STANDARD = 9, /* VPort deleted event */
|
||||
BFA_LPORT_AEN_NPIV_DUP_WWN = 10, /* VPort with duplicate WWN */
|
||||
BFA_LPORT_AEN_NPIV_FABRIC_MAX = 11, /* Max NPIV in fabric/fport */
|
||||
BFA_LPORT_AEN_NPIV_UNKNOWN = 12, /* Unknown NPIV Error code */
|
||||
};
|
||||
|
||||
struct bfa_lport_aen_data_s {
|
||||
u16 vf_id; /* vf_id of this logical port */
|
||||
u16 roles; /* Logical port mode,IM/TM/IP etc */
|
||||
u32 rsvd;
|
||||
wwn_t ppwwn; /* WWN of its physical port */
|
||||
wwn_t lpwwn; /* WWN of this logical port */
|
||||
};
|
||||
|
||||
/* BFA ITNIM events */
|
||||
enum bfa_itnim_aen_event {
|
||||
BFA_ITNIM_AEN_ONLINE = 1, /* Target online */
|
||||
BFA_ITNIM_AEN_OFFLINE = 2, /* Target offline */
|
||||
BFA_ITNIM_AEN_DISCONNECT = 3, /* Target disconnected */
|
||||
};
|
||||
|
||||
struct bfa_itnim_aen_data_s {
|
||||
u16 vf_id; /* vf_id of the IT nexus */
|
||||
u16 rsvd[3];
|
||||
wwn_t ppwwn; /* WWN of its physical port */
|
||||
wwn_t lpwwn; /* WWN of logical port */
|
||||
wwn_t rpwwn; /* WWN of remote(target) port */
|
||||
};
|
||||
|
||||
/* BFA audit events */
|
||||
enum bfa_audit_aen_event {
|
||||
BFA_AUDIT_AEN_AUTH_ENABLE = 1,
|
||||
BFA_AUDIT_AEN_AUTH_DISABLE = 2,
|
||||
BFA_AUDIT_AEN_FLASH_ERASE = 3,
|
||||
BFA_AUDIT_AEN_FLASH_UPDATE = 4,
|
||||
};
|
||||
|
||||
struct bfa_audit_aen_data_s {
|
||||
wwn_t pwwn;
|
||||
int partition_inst;
|
||||
int partition_type;
|
||||
};
|
||||
|
||||
/* BFA IOC level events */
|
||||
enum bfa_ioc_aen_event {
|
||||
BFA_IOC_AEN_HBGOOD = 1, /* Heart Beat restore event */
|
||||
BFA_IOC_AEN_HBFAIL = 2, /* Heart Beat failure event */
|
||||
BFA_IOC_AEN_ENABLE = 3, /* IOC enabled event */
|
||||
BFA_IOC_AEN_DISABLE = 4, /* IOC disabled event */
|
||||
BFA_IOC_AEN_FWMISMATCH = 5, /* IOC firmware mismatch */
|
||||
BFA_IOC_AEN_FWCFG_ERROR = 6, /* IOC firmware config error */
|
||||
BFA_IOC_AEN_INVALID_VENDOR = 7,
|
||||
BFA_IOC_AEN_INVALID_NWWN = 8, /* Zero NWWN */
|
||||
BFA_IOC_AEN_INVALID_PWWN = 9 /* Zero PWWN */
|
||||
};
|
||||
|
||||
struct bfa_ioc_aen_data_s {
|
||||
wwn_t pwwn;
|
||||
u16 ioc_type;
|
||||
mac_t mac;
|
||||
};
|
||||
|
||||
/*
|
||||
* ---------------------- mfg definitions ------------
|
||||
*/
|
||||
|
@ -587,6 +722,14 @@ struct bfa_ablk_cfg_s {
|
|||
*/
|
||||
#define SFP_DIAGMON_SIZE 10 /* num bytes of diag monitor data */
|
||||
|
||||
/* SFP state change notification event */
|
||||
#define BFA_SFP_SCN_REMOVED 0
|
||||
#define BFA_SFP_SCN_INSERTED 1
|
||||
#define BFA_SFP_SCN_POM 2
|
||||
#define BFA_SFP_SCN_FAILED 3
|
||||
#define BFA_SFP_SCN_UNSUPPORT 4
|
||||
#define BFA_SFP_SCN_VALID 5
|
||||
|
||||
enum bfa_defs_sfp_media_e {
|
||||
BFA_SFP_MEDIA_UNKNOWN = 0x00,
|
||||
BFA_SFP_MEDIA_CU = 0x01,
|
||||
|
|
|
@ -1228,4 +1228,52 @@ struct bfa_cee_stats_s {
|
|||
|
||||
#pragma pack()
|
||||
|
||||
/*
|
||||
* AEN related definitions
|
||||
*/
|
||||
#define BFAD_NL_VENDOR_ID (((u64)0x01 << SCSI_NL_VID_TYPE_SHIFT) \
|
||||
| BFA_PCI_VENDOR_ID_BROCADE)
|
||||
|
||||
/* BFA remote port events */
|
||||
enum bfa_rport_aen_event {
|
||||
BFA_RPORT_AEN_ONLINE = 1, /* RPort online event */
|
||||
BFA_RPORT_AEN_OFFLINE = 2, /* RPort offline event */
|
||||
BFA_RPORT_AEN_DISCONNECT = 3, /* RPort disconnect event */
|
||||
BFA_RPORT_AEN_QOS_PRIO = 4, /* QOS priority change event */
|
||||
BFA_RPORT_AEN_QOS_FLOWID = 5, /* QOS flow Id change event */
|
||||
};
|
||||
|
||||
struct bfa_rport_aen_data_s {
|
||||
u16 vf_id; /* vf_id of this logical port */
|
||||
u16 rsvd[3];
|
||||
wwn_t ppwwn; /* WWN of its physical port */
|
||||
wwn_t lpwwn; /* WWN of this logical port */
|
||||
wwn_t rpwwn; /* WWN of this remote port */
|
||||
union {
|
||||
struct bfa_rport_qos_attr_s qos;
|
||||
} priv;
|
||||
};
|
||||
|
||||
union bfa_aen_data_u {
|
||||
struct bfa_adapter_aen_data_s adapter;
|
||||
struct bfa_port_aen_data_s port;
|
||||
struct bfa_lport_aen_data_s lport;
|
||||
struct bfa_rport_aen_data_s rport;
|
||||
struct bfa_itnim_aen_data_s itnim;
|
||||
struct bfa_audit_aen_data_s audit;
|
||||
struct bfa_ioc_aen_data_s ioc;
|
||||
};
|
||||
|
||||
#define BFA_AEN_MAX_ENTRY 512
|
||||
|
||||
struct bfa_aen_entry_s {
|
||||
struct list_head qe;
|
||||
enum bfa_aen_category aen_category;
|
||||
u32 aen_type;
|
||||
union bfa_aen_data_u aen_data;
|
||||
struct timeval aen_tv;
|
||||
u32 seq_num;
|
||||
u32 bfad_num;
|
||||
};
|
||||
|
||||
#endif /* __BFA_DEFS_SVC_H__ */
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
#include "bfad_drv.h"
|
||||
#include "bfad_im.h"
|
||||
#include "bfa_fcs.h"
|
||||
#include "bfa_fcbuild.h"
|
||||
|
||||
|
@ -1327,6 +1328,29 @@ bfa_fcs_fabric_flogiacc_comp(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
|
|||
bfa_trc(fabric->fcs, status);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Send AEN notification
|
||||
*/
|
||||
static void
|
||||
bfa_fcs_fabric_aen_post(struct bfa_fcs_lport_s *port,
|
||||
enum bfa_port_aen_event event)
|
||||
{
|
||||
struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad;
|
||||
struct bfa_aen_entry_s *aen_entry;
|
||||
|
||||
bfad_get_aen_entry(bfad, aen_entry);
|
||||
if (!aen_entry)
|
||||
return;
|
||||
|
||||
aen_entry->aen_data.port.pwwn = bfa_fcs_lport_get_pwwn(port);
|
||||
aen_entry->aen_data.port.fwwn = bfa_fcs_lport_get_fabric_name(port);
|
||||
|
||||
/* Send the AEN notification */
|
||||
bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq,
|
||||
BFA_AEN_CAT_PORT, event);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* @param[in] fabric - fabric
|
||||
|
@ -1358,6 +1382,8 @@ bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
|
|||
BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
|
||||
"Base port WWN = %s Fabric WWN = %s\n",
|
||||
pwwn_ptr, fwwn_ptr);
|
||||
bfa_fcs_fabric_aen_post(&fabric->bport,
|
||||
BFA_PORT_AEN_FABRIC_NAME_CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -675,6 +675,7 @@ struct bfa_fcs_s {
|
|||
struct bfa_fcs_fabric_s fabric; /* base fabric state machine */
|
||||
struct bfa_fcs_stats_s stats; /* FCS statistics */
|
||||
struct bfa_wc_s wc; /* waiting counter */
|
||||
int fcs_aen_seq;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -37,6 +37,8 @@ static void bfa_fcs_itnim_prli_response(void *fcsarg,
|
|||
struct bfa_fcxp_s *fcxp, void *cbarg,
|
||||
bfa_status_t req_status, u32 rsp_len,
|
||||
u32 resid_len, struct fchs_s *rsp_fchs);
|
||||
static void bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim,
|
||||
enum bfa_itnim_aen_event event);
|
||||
|
||||
/*
|
||||
* fcs_itnim_sm FCS itnim state machine events
|
||||
|
@ -269,6 +271,7 @@ bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
|
|||
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
|
||||
"Target (WWN = %s) is online for initiator (WWN = %s)\n",
|
||||
rpwwn_buf, lpwwn_buf);
|
||||
bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_ONLINE);
|
||||
break;
|
||||
|
||||
case BFA_FCS_ITNIM_SM_OFFLINE:
|
||||
|
@ -305,14 +308,17 @@ bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
|
|||
bfa_itnim_offline(itnim->bfa_itnim);
|
||||
wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port));
|
||||
wwn2str(rpwwn_buf, itnim->rport->pwwn);
|
||||
if (bfa_fcs_lport_is_online(itnim->rport->port) == BFA_TRUE)
|
||||
if (bfa_fcs_lport_is_online(itnim->rport->port) == BFA_TRUE) {
|
||||
BFA_LOG(KERN_ERR, bfad, bfa_log_level,
|
||||
"Target (WWN = %s) connectivity lost for "
|
||||
"initiator (WWN = %s)\n", rpwwn_buf, lpwwn_buf);
|
||||
else
|
||||
bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_DISCONNECT);
|
||||
} else {
|
||||
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
|
||||
"Target (WWN = %s) offlined by initiator (WWN = %s)\n",
|
||||
rpwwn_buf, lpwwn_buf);
|
||||
bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_OFFLINE);
|
||||
}
|
||||
break;
|
||||
|
||||
case BFA_FCS_ITNIM_SM_DELETE:
|
||||
|
@ -381,6 +387,33 @@ bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim,
|
||||
enum bfa_itnim_aen_event event)
|
||||
{
|
||||
struct bfa_fcs_rport_s *rport = itnim->rport;
|
||||
struct bfad_s *bfad = (struct bfad_s *)itnim->fcs->bfad;
|
||||
struct bfa_aen_entry_s *aen_entry;
|
||||
|
||||
/* Don't post events for well known addresses */
|
||||
if (BFA_FCS_PID_IS_WKA(rport->pid))
|
||||
return;
|
||||
|
||||
bfad_get_aen_entry(bfad, aen_entry);
|
||||
if (!aen_entry)
|
||||
return;
|
||||
|
||||
aen_entry->aen_data.itnim.vf_id = rport->port->fabric->vf_id;
|
||||
aen_entry->aen_data.itnim.ppwwn = bfa_fcs_lport_get_pwwn(
|
||||
bfa_fcs_get_base_port(itnim->fcs));
|
||||
aen_entry->aen_data.itnim.lpwwn = bfa_fcs_lport_get_pwwn(rport->port);
|
||||
aen_entry->aen_data.itnim.rpwwn = rport->pwwn;
|
||||
|
||||
/* Send the AEN notification */
|
||||
bfad_im_post_vendor_event(aen_entry, bfad, ++rport->fcs->fcs_aen_seq,
|
||||
BFA_AEN_CAT_ITNIM, event);
|
||||
}
|
||||
|
||||
static void
|
||||
bfa_fcs_itnim_send_prli(void *itnim_cbarg, struct bfa_fcxp_s *fcxp_alloced)
|
||||
{
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
|
||||
#include "bfad_drv.h"
|
||||
#include "bfad_im.h"
|
||||
#include "bfa_fcs.h"
|
||||
#include "bfa_fcbuild.h"
|
||||
#include "bfa_fc.h"
|
||||
|
@ -299,6 +300,31 @@ bfa_fcs_lport_sm_deleting(
|
|||
* fcs_port_pvt
|
||||
*/
|
||||
|
||||
/*
|
||||
* Send AEN notification
|
||||
*/
|
||||
static void
|
||||
bfa_fcs_lport_aen_post(struct bfa_fcs_lport_s *port,
|
||||
enum bfa_lport_aen_event event)
|
||||
{
|
||||
struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad;
|
||||
struct bfa_aen_entry_s *aen_entry;
|
||||
|
||||
bfad_get_aen_entry(bfad, aen_entry);
|
||||
if (!aen_entry)
|
||||
return;
|
||||
|
||||
aen_entry->aen_data.lport.vf_id = port->fabric->vf_id;
|
||||
aen_entry->aen_data.lport.roles = port->port_cfg.roles;
|
||||
aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn(
|
||||
bfa_fcs_get_base_port(port->fcs));
|
||||
aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port);
|
||||
|
||||
/* Send the AEN notification */
|
||||
bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq,
|
||||
BFA_AEN_CAT_LPORT, event);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a LS reject
|
||||
*/
|
||||
|
@ -593,6 +619,7 @@ bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port)
|
|||
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
|
||||
"Logical port online: WWN = %s Role = %s\n",
|
||||
lpwwn_buf, "Initiator");
|
||||
bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_ONLINE);
|
||||
|
||||
bfad->bfad_flags |= BFAD_PORT_ONLINE;
|
||||
}
|
||||
|
@ -611,14 +638,17 @@ bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port)
|
|||
|
||||
wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
|
||||
if (bfa_sm_cmp_state(port->fabric,
|
||||
bfa_fcs_fabric_sm_online) == BFA_TRUE)
|
||||
bfa_fcs_fabric_sm_online) == BFA_TRUE) {
|
||||
BFA_LOG(KERN_ERR, bfad, bfa_log_level,
|
||||
"Logical port lost fabric connectivity: WWN = %s Role = %s\n",
|
||||
lpwwn_buf, "Initiator");
|
||||
else
|
||||
bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DISCONNECT);
|
||||
} else {
|
||||
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
|
||||
"Logical port taken offline: WWN = %s Role = %s\n",
|
||||
lpwwn_buf, "Initiator");
|
||||
bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_OFFLINE);
|
||||
}
|
||||
|
||||
list_for_each_safe(qe, qen, &port->rport_q) {
|
||||
rport = (struct bfa_fcs_rport_s *) qe;
|
||||
|
@ -676,6 +706,7 @@ bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port)
|
|||
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
|
||||
"Logical port deleted: WWN = %s Role = %s\n",
|
||||
lpwwn_buf, "Initiator");
|
||||
bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DELETE);
|
||||
|
||||
/* Base port will be deleted by the OS driver */
|
||||
if (port->vport) {
|
||||
|
@ -973,6 +1004,7 @@ bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport,
|
|||
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
|
||||
"New logical port created: WWN = %s Role = %s\n",
|
||||
lpwwn_buf, "Initiator");
|
||||
bfa_fcs_lport_aen_post(lport, BFA_LPORT_AEN_NEW);
|
||||
|
||||
bfa_sm_set_state(lport, bfa_fcs_lport_sm_uninit);
|
||||
bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
|
||||
|
@ -5558,6 +5590,31 @@ bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
|
|||
/*
|
||||
* fcs_vport_private FCS virtual port private functions
|
||||
*/
|
||||
/*
|
||||
* Send AEN notification
|
||||
*/
|
||||
static void
|
||||
bfa_fcs_vport_aen_post(struct bfa_fcs_lport_s *port,
|
||||
enum bfa_lport_aen_event event)
|
||||
{
|
||||
struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad;
|
||||
struct bfa_aen_entry_s *aen_entry;
|
||||
|
||||
bfad_get_aen_entry(bfad, aen_entry);
|
||||
if (!aen_entry)
|
||||
return;
|
||||
|
||||
aen_entry->aen_data.lport.vf_id = port->fabric->vf_id;
|
||||
aen_entry->aen_data.lport.roles = port->port_cfg.roles;
|
||||
aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn(
|
||||
bfa_fcs_get_base_port(port->fcs));
|
||||
aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port);
|
||||
|
||||
/* Send the AEN notification */
|
||||
bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq,
|
||||
BFA_AEN_CAT_LPORT, event);
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine will be called to send a FDISC command.
|
||||
*/
|
||||
|
@ -5585,8 +5642,11 @@ bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport)
|
|||
case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */
|
||||
if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
|
||||
bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
|
||||
else
|
||||
else {
|
||||
bfa_fcs_vport_aen_post(&vport->lport,
|
||||
BFA_LPORT_AEN_NPIV_DUP_WWN);
|
||||
bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_DUP_WWN);
|
||||
}
|
||||
break;
|
||||
|
||||
case FC_LS_RJT_EXP_INSUFF_RES:
|
||||
|
@ -5596,11 +5656,17 @@ bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport)
|
|||
*/
|
||||
if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
|
||||
bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
|
||||
else
|
||||
else {
|
||||
bfa_fcs_vport_aen_post(&vport->lport,
|
||||
BFA_LPORT_AEN_NPIV_FABRIC_MAX);
|
||||
bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (vport->fdisc_retries == 0)
|
||||
bfa_fcs_vport_aen_post(&vport->lport,
|
||||
BFA_LPORT_AEN_NPIV_UNKNOWN);
|
||||
bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
#include "bfad_drv.h"
|
||||
#include "bfad_im.h"
|
||||
#include "bfa_fcs.h"
|
||||
#include "bfa_fcbuild.h"
|
||||
|
||||
|
@ -2040,6 +2041,35 @@ bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport)
|
|||
kfree(rport->rp_drv);
|
||||
}
|
||||
|
||||
static void
|
||||
bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s *rport,
|
||||
enum bfa_rport_aen_event event,
|
||||
struct bfa_rport_aen_data_s *data)
|
||||
{
|
||||
struct bfa_fcs_lport_s *port = rport->port;
|
||||
struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
|
||||
struct bfa_aen_entry_s *aen_entry;
|
||||
|
||||
bfad_get_aen_entry(bfad, aen_entry);
|
||||
if (!aen_entry)
|
||||
return;
|
||||
|
||||
if (event == BFA_RPORT_AEN_QOS_PRIO)
|
||||
aen_entry->aen_data.rport.priv.qos = data->priv.qos;
|
||||
else if (event == BFA_RPORT_AEN_QOS_FLOWID)
|
||||
aen_entry->aen_data.rport.priv.qos = data->priv.qos;
|
||||
|
||||
aen_entry->aen_data.rport.vf_id = rport->port->fabric->vf_id;
|
||||
aen_entry->aen_data.rport.ppwwn = bfa_fcs_lport_get_pwwn(
|
||||
bfa_fcs_get_base_port(rport->fcs));
|
||||
aen_entry->aen_data.rport.lpwwn = bfa_fcs_lport_get_pwwn(rport->port);
|
||||
aen_entry->aen_data.rport.rpwwn = rport->pwwn;
|
||||
|
||||
/* Send the AEN notification */
|
||||
bfad_im_post_vendor_event(aen_entry, bfad, ++rport->fcs->fcs_aen_seq,
|
||||
BFA_AEN_CAT_RPORT, event);
|
||||
}
|
||||
|
||||
static void
|
||||
bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport)
|
||||
{
|
||||
|
@ -2063,10 +2093,12 @@ bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport)
|
|||
|
||||
wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
|
||||
wwn2str(rpwwn_buf, rport->pwwn);
|
||||
if (!BFA_FCS_PID_IS_WKA(rport->pid))
|
||||
if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
|
||||
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
|
||||
"Remote port (WWN = %s) online for logical port (WWN = %s)\n",
|
||||
rpwwn_buf, lpwwn_buf);
|
||||
bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_ONLINE, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2083,16 +2115,21 @@ bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport)
|
|||
wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
|
||||
wwn2str(rpwwn_buf, rport->pwwn);
|
||||
if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
|
||||
if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE)
|
||||
if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE) {
|
||||
BFA_LOG(KERN_ERR, bfad, bfa_log_level,
|
||||
"Remote port (WWN = %s) connectivity lost for "
|
||||
"logical port (WWN = %s)\n",
|
||||
rpwwn_buf, lpwwn_buf);
|
||||
else
|
||||
bfa_fcs_rport_aen_post(rport,
|
||||
BFA_RPORT_AEN_DISCONNECT, NULL);
|
||||
} else {
|
||||
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
|
||||
"Remote port (WWN = %s) offlined by "
|
||||
"logical port (WWN = %s)\n",
|
||||
rpwwn_buf, lpwwn_buf);
|
||||
bfa_fcs_rport_aen_post(rport,
|
||||
BFA_RPORT_AEN_OFFLINE, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (bfa_fcs_lport_is_initiator(port)) {
|
||||
|
@ -2366,8 +2403,11 @@ bfa_cb_rport_qos_scn_flowid(void *cbarg,
|
|||
struct bfa_rport_qos_attr_s new_qos_attr)
|
||||
{
|
||||
struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
|
||||
struct bfa_rport_aen_data_s aen_data;
|
||||
|
||||
bfa_trc(rport->fcs, rport->pwwn);
|
||||
aen_data.priv.qos = new_qos_attr;
|
||||
bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2390,8 +2430,11 @@ bfa_cb_rport_qos_scn_prio(void *cbarg,
|
|||
struct bfa_rport_qos_attr_s new_qos_attr)
|
||||
{
|
||||
struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
|
||||
struct bfa_rport_aen_data_s aen_data;
|
||||
|
||||
bfa_trc(rport->fcs, rport->pwwn);
|
||||
aen_data.priv.qos = new_qos_attr;
|
||||
bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_PRIO, &aen_data);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
|
||||
#include "bfad_drv.h"
|
||||
#include "bfad_im.h"
|
||||
#include "bfa_ioc.h"
|
||||
#include "bfi_reg.h"
|
||||
#include "bfa_defs.h"
|
||||
|
@ -458,6 +459,7 @@ bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc)
|
|||
ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
|
||||
bfa_ioc_event_notify(ioc, BFA_IOC_E_ENABLED);
|
||||
BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n");
|
||||
bfa_ioc_aen_post(ioc, BFA_IOC_AEN_ENABLE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -502,6 +504,7 @@ bfa_ioc_sm_disabling_entry(struct bfa_ioc_s *ioc)
|
|||
struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
|
||||
bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_DISABLE);
|
||||
BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC disabled\n");
|
||||
bfa_ioc_aen_post(ioc, BFA_IOC_AEN_DISABLE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1966,6 +1969,7 @@ bfa_ioc_fail_notify(struct bfa_ioc_s *ioc)
|
|||
|
||||
BFA_LOG(KERN_CRIT, bfad, bfa_log_level,
|
||||
"Heart Beat of IOC has failed\n");
|
||||
bfa_ioc_aen_post(ioc, BFA_IOC_AEN_HBFAIL);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1980,6 +1984,7 @@ bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc)
|
|||
BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
|
||||
"Running firmware version is incompatible "
|
||||
"with the driver version\n");
|
||||
bfa_ioc_aen_post(ioc, BFA_IOC_AEN_FWMISMATCH);
|
||||
}
|
||||
|
||||
bfa_status_t
|
||||
|
@ -2678,6 +2683,43 @@ bfa_ioc_get_mfg_mac(struct bfa_ioc_s *ioc)
|
|||
return m;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send AEN notification
|
||||
*/
|
||||
void
|
||||
bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
|
||||
{
|
||||
struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
|
||||
struct bfa_aen_entry_s *aen_entry;
|
||||
enum bfa_ioc_type_e ioc_type;
|
||||
|
||||
bfad_get_aen_entry(bfad, aen_entry);
|
||||
if (!aen_entry)
|
||||
return;
|
||||
|
||||
ioc_type = bfa_ioc_get_type(ioc);
|
||||
switch (ioc_type) {
|
||||
case BFA_IOC_TYPE_FC:
|
||||
aen_entry->aen_data.ioc.pwwn = ioc->attr->pwwn;
|
||||
break;
|
||||
case BFA_IOC_TYPE_FCoE:
|
||||
aen_entry->aen_data.ioc.pwwn = ioc->attr->pwwn;
|
||||
aen_entry->aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
|
||||
break;
|
||||
case BFA_IOC_TYPE_LL:
|
||||
aen_entry->aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
|
||||
break;
|
||||
default:
|
||||
WARN_ON(ioc_type != BFA_IOC_TYPE_FC);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Send the AEN notification */
|
||||
aen_entry->aen_data.ioc.ioc_type = ioc_type;
|
||||
bfad_im_post_vendor_event(aen_entry, bfad, ++ioc->ioc_aen_seq,
|
||||
BFA_AEN_CAT_IOC, event);
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve saved firmware trace from a prior IOC failure.
|
||||
*/
|
||||
|
@ -2879,6 +2921,10 @@ bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc)
|
|||
{
|
||||
if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_LL)
|
||||
return;
|
||||
if (ioc->attr->nwwn == 0)
|
||||
bfa_ioc_aen_post(ioc, BFA_IOC_AEN_INVALID_NWWN);
|
||||
if (ioc->attr->pwwn == 0)
|
||||
bfa_ioc_aen_post(ioc, BFA_IOC_AEN_INVALID_PWWN);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3442,6 +3488,54 @@ bfa_sfp_notify(void *sfp_arg, enum bfa_ioc_event_e event)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SFP's State Change Notification post to AEN
|
||||
*/
|
||||
static void
|
||||
bfa_sfp_scn_aen_post(struct bfa_sfp_s *sfp, struct bfi_sfp_scn_s *rsp)
|
||||
{
|
||||
struct bfad_s *bfad = (struct bfad_s *)sfp->ioc->bfa->bfad;
|
||||
struct bfa_aen_entry_s *aen_entry;
|
||||
enum bfa_port_aen_event aen_evt = 0;
|
||||
|
||||
bfa_trc(sfp, (((u64)rsp->pomlvl) << 16) | (((u64)rsp->sfpid) << 8) |
|
||||
((u64)rsp->event));
|
||||
|
||||
bfad_get_aen_entry(bfad, aen_entry);
|
||||
if (!aen_entry)
|
||||
return;
|
||||
|
||||
aen_entry->aen_data.port.ioc_type = bfa_ioc_get_type(sfp->ioc);
|
||||
aen_entry->aen_data.port.pwwn = sfp->ioc->attr->pwwn;
|
||||
aen_entry->aen_data.port.mac = bfa_ioc_get_mac(sfp->ioc);
|
||||
|
||||
switch (rsp->event) {
|
||||
case BFA_SFP_SCN_INSERTED:
|
||||
aen_evt = BFA_PORT_AEN_SFP_INSERT;
|
||||
break;
|
||||
case BFA_SFP_SCN_REMOVED:
|
||||
aen_evt = BFA_PORT_AEN_SFP_REMOVE;
|
||||
break;
|
||||
case BFA_SFP_SCN_FAILED:
|
||||
aen_evt = BFA_PORT_AEN_SFP_ACCESS_ERROR;
|
||||
break;
|
||||
case BFA_SFP_SCN_UNSUPPORT:
|
||||
aen_evt = BFA_PORT_AEN_SFP_UNSUPPORT;
|
||||
break;
|
||||
case BFA_SFP_SCN_POM:
|
||||
aen_evt = BFA_PORT_AEN_SFP_POM;
|
||||
aen_entry->aen_data.port.level = rsp->pomlvl;
|
||||
break;
|
||||
default:
|
||||
bfa_trc(sfp, rsp->event);
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
||||
/* Send the AEN notification */
|
||||
bfad_im_post_vendor_event(aen_entry, bfad, ++sfp->ioc->ioc_aen_seq,
|
||||
BFA_AEN_CAT_PORT, aen_evt);
|
||||
}
|
||||
|
||||
/*
|
||||
* SFP get data send
|
||||
*/
|
||||
|
@ -3481,6 +3575,50 @@ bfa_sfp_getdata(struct bfa_sfp_s *sfp, enum bfi_sfp_mem_e memtype)
|
|||
bfa_sfp_getdata_send(sfp);
|
||||
}
|
||||
|
||||
/*
|
||||
* SFP scn handler
|
||||
*/
|
||||
static void
|
||||
bfa_sfp_scn(struct bfa_sfp_s *sfp, struct bfi_mbmsg_s *msg)
|
||||
{
|
||||
struct bfi_sfp_scn_s *rsp = (struct bfi_sfp_scn_s *) msg;
|
||||
|
||||
switch (rsp->event) {
|
||||
case BFA_SFP_SCN_INSERTED:
|
||||
sfp->state = BFA_SFP_STATE_INSERTED;
|
||||
sfp->data_valid = 0;
|
||||
bfa_sfp_scn_aen_post(sfp, rsp);
|
||||
break;
|
||||
case BFA_SFP_SCN_REMOVED:
|
||||
sfp->state = BFA_SFP_STATE_REMOVED;
|
||||
sfp->data_valid = 0;
|
||||
bfa_sfp_scn_aen_post(sfp, rsp);
|
||||
break;
|
||||
case BFA_SFP_SCN_FAILED:
|
||||
sfp->state = BFA_SFP_STATE_FAILED;
|
||||
sfp->data_valid = 0;
|
||||
bfa_sfp_scn_aen_post(sfp, rsp);
|
||||
break;
|
||||
case BFA_SFP_SCN_UNSUPPORT:
|
||||
sfp->state = BFA_SFP_STATE_UNSUPPORT;
|
||||
bfa_sfp_scn_aen_post(sfp, rsp);
|
||||
if (!sfp->lock)
|
||||
bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL);
|
||||
break;
|
||||
case BFA_SFP_SCN_POM:
|
||||
bfa_sfp_scn_aen_post(sfp, rsp);
|
||||
break;
|
||||
case BFA_SFP_SCN_VALID:
|
||||
sfp->state = BFA_SFP_STATE_VALID;
|
||||
if (!sfp->lock)
|
||||
bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL);
|
||||
break;
|
||||
default:
|
||||
bfa_trc(sfp, rsp->event);
|
||||
WARN_ON(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SFP show complete
|
||||
*/
|
||||
|
@ -3645,7 +3783,7 @@ bfa_sfp_intr(void *sfparg, struct bfi_mbmsg_s *msg)
|
|||
break;
|
||||
|
||||
case BFI_SFP_I2H_SCN:
|
||||
bfa_trc(sfp, msg->mh.msg_id);
|
||||
bfa_sfp_scn(sfp, msg);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -3837,6 +3975,26 @@ bfa_sfp_speed(struct bfa_sfp_s *sfp, enum bfa_port_speed portspeed,
|
|||
#define BFA_FLASH_DMA_BUF_SZ \
|
||||
BFA_ROUNDUP(0x010000 + sizeof(struct bfa_mfg_block_s), BFA_FLASH_SEG_SZ)
|
||||
|
||||
static void
|
||||
bfa_flash_aen_audit_post(struct bfa_ioc_s *ioc, enum bfa_audit_aen_event event,
|
||||
int inst, int type)
|
||||
{
|
||||
struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
|
||||
struct bfa_aen_entry_s *aen_entry;
|
||||
|
||||
bfad_get_aen_entry(bfad, aen_entry);
|
||||
if (!aen_entry)
|
||||
return;
|
||||
|
||||
aen_entry->aen_data.audit.pwwn = ioc->attr->pwwn;
|
||||
aen_entry->aen_data.audit.partition_inst = inst;
|
||||
aen_entry->aen_data.audit.partition_type = type;
|
||||
|
||||
/* Send the AEN notification */
|
||||
bfad_im_post_vendor_event(aen_entry, bfad, ++ioc->ioc_aen_seq,
|
||||
BFA_AEN_CAT_AUDIT, event);
|
||||
}
|
||||
|
||||
static void
|
||||
bfa_flash_cb(struct bfa_flash_s *flash)
|
||||
{
|
||||
|
@ -3978,6 +4136,7 @@ bfa_flash_intr(void *flasharg, struct bfi_mbmsg_s *msg)
|
|||
struct bfi_flash_erase_rsp_s *erase;
|
||||
struct bfi_flash_write_rsp_s *write;
|
||||
struct bfi_flash_read_rsp_s *read;
|
||||
struct bfi_flash_event_s *event;
|
||||
struct bfi_mbmsg_s *msg;
|
||||
} m;
|
||||
|
||||
|
@ -4061,8 +4220,19 @@ bfa_flash_intr(void *flasharg, struct bfi_mbmsg_s *msg)
|
|||
}
|
||||
break;
|
||||
case BFI_FLASH_I2H_BOOT_VER_RSP:
|
||||
break;
|
||||
case BFI_FLASH_I2H_EVENT:
|
||||
bfa_trc(flash, msg->mh.msg_id);
|
||||
status = be32_to_cpu(m.event->status);
|
||||
bfa_trc(flash, status);
|
||||
if (status == BFA_STATUS_BAD_FWCFG)
|
||||
bfa_ioc_aen_post(flash->ioc, BFA_IOC_AEN_FWCFG_ERROR);
|
||||
else if (status == BFA_STATUS_INVALID_VENDOR) {
|
||||
u32 param;
|
||||
param = be32_to_cpu(m.event->param);
|
||||
bfa_trc(flash, param);
|
||||
bfa_ioc_aen_post(flash->ioc,
|
||||
BFA_IOC_AEN_INVALID_VENDOR);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -4204,6 +4374,8 @@ bfa_flash_erase_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type,
|
|||
flash->instance = instance;
|
||||
|
||||
bfa_flash_erase_send(flash);
|
||||
bfa_flash_aen_audit_post(flash->ioc, BFA_AUDIT_AEN_FLASH_ERASE,
|
||||
instance, type);
|
||||
return BFA_STATUS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -327,6 +327,7 @@ struct bfa_ioc_s {
|
|||
enum bfa_mode_s port_mode;
|
||||
u8 ad_cap_bm; /* adapter cap bit mask */
|
||||
u8 port_mode_cfg; /* config port mode */
|
||||
int ioc_aen_seq;
|
||||
};
|
||||
|
||||
struct bfa_ioc_hwif_s {
|
||||
|
@ -803,6 +804,7 @@ void bfa_ioc_fwver_get(struct bfa_ioc_s *ioc,
|
|||
struct bfi_ioc_image_hdr_s *fwhdr);
|
||||
bfa_boolean_t bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc,
|
||||
struct bfi_ioc_image_hdr_s *fwhdr);
|
||||
void bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event);
|
||||
bfa_status_t bfa_ioc_fw_stats_get(struct bfa_ioc_s *ioc, void *stats);
|
||||
bfa_status_t bfa_ioc_fw_stats_clear(struct bfa_ioc_s *ioc);
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@ struct bfa_s {
|
|||
struct list_head reqq_waitq[BFI_IOC_MAX_CQS];
|
||||
bfa_boolean_t fcs; /* FCS is attached to BFA */
|
||||
struct bfa_msix_s msix;
|
||||
int bfa_aen_seq;
|
||||
};
|
||||
|
||||
extern bfa_boolean_t bfa_auto_recover;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
|
||||
#include "bfad_drv.h"
|
||||
#include "bfad_im.h"
|
||||
#include "bfa_plog.h"
|
||||
#include "bfa_cs.h"
|
||||
#include "bfa_modules.h"
|
||||
|
@ -2007,6 +2008,24 @@ bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bfa_fcport_aen_post(struct bfa_fcport_s *fcport, enum bfa_port_aen_event event)
|
||||
{
|
||||
struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad;
|
||||
struct bfa_aen_entry_s *aen_entry;
|
||||
|
||||
bfad_get_aen_entry(bfad, aen_entry);
|
||||
if (!aen_entry)
|
||||
return;
|
||||
|
||||
aen_entry->aen_data.port.ioc_type = bfa_get_type(fcport->bfa);
|
||||
aen_entry->aen_data.port.pwwn = fcport->pwwn;
|
||||
|
||||
/* Send the AEN notification */
|
||||
bfad_im_post_vendor_event(aen_entry, bfad, ++fcport->bfa->bfa_aen_seq,
|
||||
BFA_AEN_CAT_PORT, event);
|
||||
}
|
||||
|
||||
/*
|
||||
* FC PORT state machine functions
|
||||
*/
|
||||
|
@ -2095,6 +2114,7 @@ bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
|
|||
wwn2str(pwwn_buf, fcport->pwwn);
|
||||
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
|
||||
"Base port disabled: WWN = %s\n", pwwn_buf);
|
||||
bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
|
||||
break;
|
||||
|
||||
case BFA_FCPORT_SM_LINKUP:
|
||||
|
@ -2155,6 +2175,7 @@ bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
|
|||
wwn2str(pwwn_buf, fcport->pwwn);
|
||||
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
|
||||
"Base port disabled: WWN = %s\n", pwwn_buf);
|
||||
bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
|
||||
break;
|
||||
|
||||
case BFA_FCPORT_SM_STOP:
|
||||
|
@ -2208,6 +2229,7 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
|
|||
wwn2str(pwwn_buf, fcport->pwwn);
|
||||
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
|
||||
"Base port online: WWN = %s\n", pwwn_buf);
|
||||
bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE);
|
||||
break;
|
||||
|
||||
case BFA_FCPORT_SM_LINKDOWN:
|
||||
|
@ -2234,6 +2256,7 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
|
|||
wwn2str(pwwn_buf, fcport->pwwn);
|
||||
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
|
||||
"Base port disabled: WWN = %s\n", pwwn_buf);
|
||||
bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
|
||||
break;
|
||||
|
||||
case BFA_FCPORT_SM_STOP:
|
||||
|
@ -2279,8 +2302,10 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
|
|||
wwn2str(pwwn_buf, fcport->pwwn);
|
||||
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
|
||||
"Base port offline: WWN = %s\n", pwwn_buf);
|
||||
bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
|
||||
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
|
||||
"Base port disabled: WWN = %s\n", pwwn_buf);
|
||||
bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
|
||||
break;
|
||||
|
||||
case BFA_FCPORT_SM_LINKDOWN:
|
||||
|
@ -2290,26 +2315,32 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
|
|||
bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
|
||||
BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
|
||||
wwn2str(pwwn_buf, fcport->pwwn);
|
||||
if (BFA_PORT_IS_DISABLED(fcport->bfa))
|
||||
if (BFA_PORT_IS_DISABLED(fcport->bfa)) {
|
||||
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
|
||||
"Base port offline: WWN = %s\n", pwwn_buf);
|
||||
else
|
||||
bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
|
||||
} else {
|
||||
BFA_LOG(KERN_ERR, bfad, bfa_log_level,
|
||||
"Base port (WWN = %s) "
|
||||
"lost fabric connectivity\n", pwwn_buf);
|
||||
bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
|
||||
}
|
||||
break;
|
||||
|
||||
case BFA_FCPORT_SM_STOP:
|
||||
bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
|
||||
bfa_fcport_reset_linkinfo(fcport);
|
||||
wwn2str(pwwn_buf, fcport->pwwn);
|
||||
if (BFA_PORT_IS_DISABLED(fcport->bfa))
|
||||
if (BFA_PORT_IS_DISABLED(fcport->bfa)) {
|
||||
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
|
||||
"Base port offline: WWN = %s\n", pwwn_buf);
|
||||
else
|
||||
bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
|
||||
} else {
|
||||
BFA_LOG(KERN_ERR, bfad, bfa_log_level,
|
||||
"Base port (WWN = %s) "
|
||||
"lost fabric connectivity\n", pwwn_buf);
|
||||
bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
|
||||
}
|
||||
break;
|
||||
|
||||
case BFA_FCPORT_SM_HWFAIL:
|
||||
|
@ -2317,13 +2348,16 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
|
|||
bfa_fcport_reset_linkinfo(fcport);
|
||||
bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE);
|
||||
wwn2str(pwwn_buf, fcport->pwwn);
|
||||
if (BFA_PORT_IS_DISABLED(fcport->bfa))
|
||||
if (BFA_PORT_IS_DISABLED(fcport->bfa)) {
|
||||
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
|
||||
"Base port offline: WWN = %s\n", pwwn_buf);
|
||||
else
|
||||
bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
|
||||
} else {
|
||||
BFA_LOG(KERN_ERR, bfad, bfa_log_level,
|
||||
"Base port (WWN = %s) "
|
||||
"lost fabric connectivity\n", pwwn_buf);
|
||||
bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -2454,6 +2488,7 @@ bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
|
|||
wwn2str(pwwn_buf, fcport->pwwn);
|
||||
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
|
||||
"Base port enabled: WWN = %s\n", pwwn_buf);
|
||||
bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
|
||||
break;
|
||||
|
||||
case BFA_FCPORT_SM_STOP:
|
||||
|
@ -2508,6 +2543,7 @@ bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
|
|||
wwn2str(pwwn_buf, fcport->pwwn);
|
||||
BFA_LOG(KERN_INFO, bfad, bfa_log_level,
|
||||
"Base port enabled: WWN = %s\n", pwwn_buf);
|
||||
bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
|
||||
break;
|
||||
|
||||
case BFA_FCPORT_SM_DISABLE:
|
||||
|
|
|
@ -1348,7 +1348,7 @@ int
|
|||
bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
|
||||
{
|
||||
struct bfad_s *bfad;
|
||||
int error = -ENODEV, retval;
|
||||
int error = -ENODEV, retval, i;
|
||||
|
||||
/* For single port cards - only claim function 0 */
|
||||
if ((pdev->device == BFA_PCI_DEVICE_ID_FC_8G1P) &&
|
||||
|
@ -1372,6 +1372,12 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
|
|||
bfa_trc_init(bfad->trcmod);
|
||||
bfa_trc(bfad, bfad_inst);
|
||||
|
||||
/* AEN INIT */
|
||||
INIT_LIST_HEAD(&bfad->free_aen_q);
|
||||
INIT_LIST_HEAD(&bfad->active_aen_q);
|
||||
for (i = 0; i < BFA_AEN_MAX_ENTRY; i++)
|
||||
list_add_tail(&bfad->aen_list[i].qe, &bfad->free_aen_q);
|
||||
|
||||
if (!(bfad_load_fwimg(pdev))) {
|
||||
kfree(bfad->trcmod);
|
||||
goto out_alloc_trace_failure;
|
||||
|
|
|
@ -90,6 +90,7 @@ bfad_iocmd_ioc_get_info(struct bfad_s *bfad, void *cmd)
|
|||
bfa_get_adapter_serial_num(&bfad->bfa, iocmd->serialnum);
|
||||
iocmd->factorynwwn = pattr.factorynwwn;
|
||||
iocmd->factorypwwn = pattr.factorypwwn;
|
||||
iocmd->bfad_num = bfad->inst_no;
|
||||
im_port = bfad->pport.im_port;
|
||||
iocmd->host = im_port->shost->host_no;
|
||||
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
|
||||
|
|
|
@ -224,6 +224,10 @@ struct bfad_s {
|
|||
char *regdata;
|
||||
u32 reglen;
|
||||
struct dentry *bfad_dentry_files[5];
|
||||
struct list_head free_aen_q;
|
||||
struct list_head active_aen_q;
|
||||
struct bfa_aen_entry_s aen_list[BFA_AEN_MAX_ENTRY];
|
||||
spinlock_t bfad_aen_spinlock;
|
||||
};
|
||||
|
||||
/* BFAD state machine events */
|
||||
|
|
|
@ -656,6 +656,31 @@ bfad_im_port_clean(struct bfad_im_port_s *im_port)
|
|||
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
|
||||
}
|
||||
|
||||
static void bfad_aen_im_notify_handler(struct work_struct *work)
|
||||
{
|
||||
struct bfad_im_s *im =
|
||||
container_of(work, struct bfad_im_s, aen_im_notify_work);
|
||||
struct bfa_aen_entry_s *aen_entry;
|
||||
struct bfad_s *bfad = im->bfad;
|
||||
struct Scsi_Host *shost = bfad->pport.im_port->shost;
|
||||
void *event_data;
|
||||
unsigned long flags;
|
||||
|
||||
while (!list_empty(&bfad->active_aen_q)) {
|
||||
spin_lock_irqsave(&bfad->bfad_aen_spinlock, flags);
|
||||
bfa_q_deq(&bfad->active_aen_q, &aen_entry);
|
||||
spin_unlock_irqrestore(&bfad->bfad_aen_spinlock, flags);
|
||||
event_data = (char *)aen_entry + sizeof(struct list_head);
|
||||
fc_host_post_vendor_event(shost, fc_get_event_number(),
|
||||
sizeof(struct bfa_aen_entry_s) -
|
||||
sizeof(struct list_head),
|
||||
(char *)event_data, BFAD_NL_VENDOR_ID);
|
||||
spin_lock_irqsave(&bfad->bfad_aen_spinlock, flags);
|
||||
list_add_tail(&aen_entry->qe, &bfad->free_aen_q);
|
||||
spin_unlock_irqrestore(&bfad->bfad_aen_spinlock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
bfa_status_t
|
||||
bfad_im_probe(struct bfad_s *bfad)
|
||||
{
|
||||
|
@ -676,6 +701,7 @@ bfad_im_probe(struct bfad_s *bfad)
|
|||
rc = BFA_STATUS_FAILED;
|
||||
}
|
||||
|
||||
INIT_WORK(&im->aen_im_notify_work, bfad_aen_im_notify_handler);
|
||||
ext:
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -115,8 +115,30 @@ struct bfad_im_s {
|
|||
struct bfad_s *bfad;
|
||||
struct workqueue_struct *drv_workq;
|
||||
char drv_workq_name[KOBJ_NAME_LEN];
|
||||
struct work_struct aen_im_notify_work;
|
||||
};
|
||||
|
||||
#define bfad_get_aen_entry(_drv, _entry) do { \
|
||||
unsigned long _flags; \
|
||||
spin_lock_irqsave(&(_drv)->bfad_aen_spinlock, _flags); \
|
||||
bfa_q_deq(&(_drv)->free_aen_q, &(_entry)); \
|
||||
if (_entry) \
|
||||
list_add_tail(&(_entry)->qe, &(_drv)->active_aen_q); \
|
||||
spin_unlock_irqrestore(&(_drv)->bfad_aen_spinlock, _flags); \
|
||||
} while (0)
|
||||
|
||||
/* post fc_host vendor event */
|
||||
#define bfad_im_post_vendor_event(_entry, _drv, _cnt, _cat, _evt) do { \
|
||||
do_gettimeofday(&(_entry)->aen_tv); \
|
||||
(_entry)->bfad_num = (_drv)->inst_no; \
|
||||
(_entry)->seq_num = (_cnt); \
|
||||
(_entry)->aen_category = (_cat); \
|
||||
(_entry)->aen_type = (_evt); \
|
||||
if ((_drv)->bfad_flags & BFAD_FC4_PROBE_DONE) \
|
||||
queue_work((_drv)->im->drv_workq, \
|
||||
&(_drv)->im->aen_im_notify_work); \
|
||||
} while (0)
|
||||
|
||||
struct Scsi_Host *bfad_scsi_host_alloc(struct bfad_im_port_s *im_port,
|
||||
struct bfad_s *);
|
||||
bfa_status_t bfad_thread_workq(struct bfad_s *bfad);
|
||||
|
|
|
@ -783,6 +783,17 @@ enum bfi_sfp_i2h_e {
|
|||
BFI_SFP_I2H_SCN = BFA_I2HM(BFI_SFP_H2I_SCN),
|
||||
};
|
||||
|
||||
/*
|
||||
* SFP state change notification
|
||||
*/
|
||||
struct bfi_sfp_scn_s {
|
||||
struct bfi_mhdr_s mhr; /* host msg header */
|
||||
u8 event;
|
||||
u8 sfpid;
|
||||
u8 pomlvl; /* pom level: normal/warning/alarm */
|
||||
u8 is_elb; /* e-loopback */
|
||||
};
|
||||
|
||||
/*
|
||||
* SFP state
|
||||
*/
|
||||
|
@ -925,6 +936,15 @@ struct bfi_flash_erase_rsp_s {
|
|||
u32 status;
|
||||
};
|
||||
|
||||
/*
|
||||
* Flash event notification
|
||||
*/
|
||||
struct bfi_flash_event_s {
|
||||
struct bfi_mhdr_s mh; /* Common msg header */
|
||||
bfa_status_t status;
|
||||
u32 param;
|
||||
};
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
* DIAG
|
||||
|
|
Loading…
Reference in New Issue