scsi: lpfc: add Trunking support

Add trunking support to the driver. Trunking is found on more recent
asics. In general, trunking appears as a single "port" to the driver
and overall behavior doesn't differ. Link speed is reported as an
aggregate value, while link speed control is done on a per-physical
link basis with all links in the trunk symmetrical. Some commands
returning port information are updated to additionally provide
trunking information. And new ACQEs are generated to report physical
link events relative to the trunk.

This patch contains the following modifications:

- Added link speed settings of 128GB and 256GB.

- Added handling of trunk-related ACQEs, mainly logging and trapping
  of physical link statuses.

- Added additional bsg interface to query trunk state by applications.

- Augment link_state sysfs attribtute to display trunk link status

Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: James Smart <jsmart2021@gmail.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
James Smart
2018-10-23 13:41:11 -07:00
committed by Martin K. Petersen
parent 7ea92eb458
commit 1dc5ec2452
12 changed files with 474 additions and 0 deletions

View File

@@ -5615,6 +5615,77 @@ ras_job_error:
return rc;
}
static int
lpfc_get_trunk_info(struct bsg_job *job)
{
struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
struct lpfc_hba *phba = vport->phba;
struct fc_bsg_reply *bsg_reply = job->reply;
struct lpfc_trunk_info *event_reply;
int rc = 0;
if (job->request_len <
sizeof(struct fc_bsg_request) + sizeof(struct get_trunk_info_req)) {
lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
"2744 Received GET TRUNK _INFO request below "
"minimum size\n");
rc = -EINVAL;
goto job_error;
}
event_reply = (struct lpfc_trunk_info *)
bsg_reply->reply_data.vendor_reply.vendor_rsp;
if (job->reply_len <
sizeof(struct fc_bsg_request) + sizeof(struct lpfc_trunk_info)) {
lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
"2728 Received GET TRUNK _INFO reply below "
"minimum size\n");
rc = -EINVAL;
goto job_error;
}
if (event_reply == NULL) {
rc = -EINVAL;
goto job_error;
}
bsg_bf_set(lpfc_trunk_info_link_status, event_reply,
(phba->link_state >= LPFC_LINK_UP) ? 1 : 0);
bsg_bf_set(lpfc_trunk_info_trunk_active0, event_reply,
(phba->trunk_link.link0.state == LPFC_LINK_UP) ? 1 : 0);
bsg_bf_set(lpfc_trunk_info_trunk_active1, event_reply,
(phba->trunk_link.link1.state == LPFC_LINK_UP) ? 1 : 0);
bsg_bf_set(lpfc_trunk_info_trunk_active2, event_reply,
(phba->trunk_link.link2.state == LPFC_LINK_UP) ? 1 : 0);
bsg_bf_set(lpfc_trunk_info_trunk_active3, event_reply,
(phba->trunk_link.link3.state == LPFC_LINK_UP) ? 1 : 0);
bsg_bf_set(lpfc_trunk_info_trunk_config0, event_reply,
bf_get(lpfc_conf_trunk_port0, &phba->sli4_hba));
bsg_bf_set(lpfc_trunk_info_trunk_config1, event_reply,
bf_get(lpfc_conf_trunk_port1, &phba->sli4_hba));
bsg_bf_set(lpfc_trunk_info_trunk_config2, event_reply,
bf_get(lpfc_conf_trunk_port2, &phba->sli4_hba));
bsg_bf_set(lpfc_trunk_info_trunk_config3, event_reply,
bf_get(lpfc_conf_trunk_port3, &phba->sli4_hba));
event_reply->port_speed = phba->sli4_hba.link_state.speed / 1000;
event_reply->logical_speed =
phba->sli4_hba.link_state.logical_speed / 100;
job_error:
bsg_reply->result = rc;
bsg_job_done(job, bsg_reply->result,
bsg_reply->reply_payload_rcv_len);
return rc;
}
/**
* lpfc_bsg_hst_vendor - process a vendor-specific fc_bsg_job
@@ -5675,6 +5746,9 @@ lpfc_bsg_hst_vendor(struct bsg_job *job)
case LPFC_BSG_VENDOR_RAS_SET_CONFIG:
rc = lpfc_bsg_set_ras_config(job);
break;
case LPFC_BSG_VENDOR_GET_TRUNK_INFO:
rc = lpfc_get_trunk_info(job);
break;
default:
rc = -EINVAL;
bsg_reply->reply_payload_rcv_len = 0;