diff options
| -rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 1 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 237 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 2 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_hw.h | 2 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_hw4.h | 149 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 144 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_sli4.h | 6 |
7 files changed, 536 insertions, 5 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 3df2b39dd87a..9d0bfba5461e 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
| @@ -660,6 +660,7 @@ struct lpfc_hba { | |||
| 660 | uint32_t cfg_hostmem_hgp; | 660 | uint32_t cfg_hostmem_hgp; |
| 661 | uint32_t cfg_log_verbose; | 661 | uint32_t cfg_log_verbose; |
| 662 | uint32_t cfg_aer_support; | 662 | uint32_t cfg_aer_support; |
| 663 | uint32_t cfg_sriov_nr_virtfn; | ||
| 663 | uint32_t cfg_iocb_cnt; | 664 | uint32_t cfg_iocb_cnt; |
| 664 | uint32_t cfg_suppress_link_up; | 665 | uint32_t cfg_suppress_link_up; |
| 665 | #define LPFC_INITIALIZE_LINK 0 /* do normal init_link mbox */ | 666 | #define LPFC_INITIALIZE_LINK 0 /* do normal init_link mbox */ |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 44816be4d724..6ecd6daffc15 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
| @@ -1384,6 +1384,102 @@ lpfc_dss_show(struct device *dev, struct device_attribute *attr, | |||
| 1384 | } | 1384 | } |
| 1385 | 1385 | ||
| 1386 | /** | 1386 | /** |
| 1387 | * lpfc_sriov_hw_max_virtfn_show - Return maximum number of virtual functions | ||
| 1388 | * @dev: class converted to a Scsi_host structure. | ||
| 1389 | * @attr: device attribute, not used. | ||
| 1390 | * @buf: on return contains the formatted support level. | ||
| 1391 | * | ||
| 1392 | * Description: | ||
| 1393 | * Returns the maximum number of virtual functions a physical function can | ||
| 1394 | * support, 0 will be returned if called on virtual function. | ||
| 1395 | * | ||
| 1396 | * Returns: size of formatted string. | ||
| 1397 | **/ | ||
| 1398 | static ssize_t | ||
| 1399 | lpfc_sriov_hw_max_virtfn_show(struct device *dev, | ||
| 1400 | struct device_attribute *attr, | ||
| 1401 | char *buf) | ||
| 1402 | { | ||
| 1403 | struct Scsi_Host *shost = class_to_shost(dev); | ||
| 1404 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | ||
| 1405 | struct lpfc_hba *phba = vport->phba; | ||
| 1406 | struct pci_dev *pdev = phba->pcidev; | ||
| 1407 | union lpfc_sli4_cfg_shdr *shdr; | ||
| 1408 | uint32_t shdr_status, shdr_add_status; | ||
| 1409 | LPFC_MBOXQ_t *mboxq; | ||
| 1410 | struct lpfc_mbx_get_prof_cfg *get_prof_cfg; | ||
| 1411 | struct lpfc_rsrc_desc_pcie *desc; | ||
| 1412 | uint32_t max_nr_virtfn; | ||
| 1413 | uint32_t desc_count; | ||
| 1414 | int length, rc, i; | ||
| 1415 | |||
| 1416 | if ((phba->sli_rev < LPFC_SLI_REV4) || | ||
| 1417 | (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != | ||
| 1418 | LPFC_SLI_INTF_IF_TYPE_2)) | ||
| 1419 | return -EPERM; | ||
| 1420 | |||
| 1421 | if (!pdev->is_physfn) | ||
| 1422 | return snprintf(buf, PAGE_SIZE, "%d\n", 0); | ||
| 1423 | |||
| 1424 | mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
| 1425 | if (!mboxq) | ||
| 1426 | return -ENOMEM; | ||
| 1427 | |||
| 1428 | /* get the maximum number of virtfn support by physfn */ | ||
| 1429 | length = (sizeof(struct lpfc_mbx_get_prof_cfg) - | ||
| 1430 | sizeof(struct lpfc_sli4_cfg_mhdr)); | ||
| 1431 | lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON, | ||
| 1432 | LPFC_MBOX_OPCODE_GET_PROFILE_CONFIG, | ||
| 1433 | length, LPFC_SLI4_MBX_EMBED); | ||
| 1434 | shdr = (union lpfc_sli4_cfg_shdr *) | ||
| 1435 | &mboxq->u.mqe.un.sli4_config.header.cfg_shdr; | ||
| 1436 | bf_set(lpfc_mbox_hdr_pf_num, &shdr->request, | ||
| 1437 | phba->sli4_hba.iov.pf_number + 1); | ||
| 1438 | |||
| 1439 | get_prof_cfg = &mboxq->u.mqe.un.get_prof_cfg; | ||
| 1440 | bf_set(lpfc_mbx_get_prof_cfg_prof_tp, &get_prof_cfg->u.request, | ||
| 1441 | LPFC_CFG_TYPE_CURRENT_ACTIVE); | ||
| 1442 | |||
| 1443 | rc = lpfc_sli_issue_mbox_wait(phba, mboxq, | ||
| 1444 | lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG)); | ||
| 1445 | |||
| 1446 | if (rc != MBX_TIMEOUT) { | ||
| 1447 | /* check return status */ | ||
| 1448 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | ||
| 1449 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, | ||
| 1450 | &shdr->response); | ||
| 1451 | if (shdr_status || shdr_add_status || rc) | ||
| 1452 | goto error_out; | ||
| 1453 | |||
| 1454 | } else | ||
| 1455 | goto error_out; | ||
| 1456 | |||
| 1457 | desc_count = get_prof_cfg->u.response.prof_cfg.rsrc_desc_count; | ||
| 1458 | |||
| 1459 | for (i = 0; i < LPFC_RSRC_DESC_MAX_NUM; i++) { | ||
| 1460 | desc = (struct lpfc_rsrc_desc_pcie *) | ||
| 1461 | &get_prof_cfg->u.response.prof_cfg.desc[i]; | ||
| 1462 | if (LPFC_RSRC_DESC_TYPE_PCIE == | ||
| 1463 | bf_get(lpfc_rsrc_desc_pcie_type, desc)) { | ||
| 1464 | max_nr_virtfn = bf_get(lpfc_rsrc_desc_pcie_nr_virtfn, | ||
| 1465 | desc); | ||
| 1466 | break; | ||
| 1467 | } | ||
| 1468 | } | ||
| 1469 | |||
| 1470 | if (i < LPFC_RSRC_DESC_MAX_NUM) { | ||
| 1471 | if (rc != MBX_TIMEOUT) | ||
| 1472 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
| 1473 | return snprintf(buf, PAGE_SIZE, "%d\n", max_nr_virtfn); | ||
| 1474 | } | ||
| 1475 | |||
| 1476 | error_out: | ||
| 1477 | if (rc != MBX_TIMEOUT) | ||
| 1478 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
| 1479 | return -EIO; | ||
| 1480 | } | ||
| 1481 | |||
| 1482 | /** | ||
| 1387 | * lpfc_param_show - Return a cfg attribute value in decimal | 1483 | * lpfc_param_show - Return a cfg attribute value in decimal |
| 1388 | * | 1484 | * |
| 1389 | * Description: | 1485 | * Description: |
| @@ -1824,6 +1920,8 @@ static DEVICE_ATTR(lpfc_temp_sensor, S_IRUGO, lpfc_temp_sensor_show, NULL); | |||
| 1824 | static DEVICE_ATTR(lpfc_fips_level, S_IRUGO, lpfc_fips_level_show, NULL); | 1920 | static DEVICE_ATTR(lpfc_fips_level, S_IRUGO, lpfc_fips_level_show, NULL); |
| 1825 | static DEVICE_ATTR(lpfc_fips_rev, S_IRUGO, lpfc_fips_rev_show, NULL); | 1921 | static DEVICE_ATTR(lpfc_fips_rev, S_IRUGO, lpfc_fips_rev_show, NULL); |
| 1826 | static DEVICE_ATTR(lpfc_dss, S_IRUGO, lpfc_dss_show, NULL); | 1922 | static DEVICE_ATTR(lpfc_dss, S_IRUGO, lpfc_dss_show, NULL); |
| 1923 | static DEVICE_ATTR(lpfc_sriov_hw_max_virtfn, S_IRUGO, | ||
| 1924 | lpfc_sriov_hw_max_virtfn_show, NULL); | ||
| 1827 | 1925 | ||
| 1828 | static char *lpfc_soft_wwn_key = "C99G71SL8032A"; | 1926 | static char *lpfc_soft_wwn_key = "C99G71SL8032A"; |
| 1829 | 1927 | ||
| @@ -3076,7 +3174,7 @@ static DEVICE_ATTR(lpfc_link_speed, S_IRUGO | S_IWUSR, | |||
| 3076 | * | 3174 | * |
| 3077 | * @dev: class device that is converted into a Scsi_host. | 3175 | * @dev: class device that is converted into a Scsi_host. |
| 3078 | * @attr: device attribute, not used. | 3176 | * @attr: device attribute, not used. |
| 3079 | * @buf: containing the string "selective". | 3177 | * @buf: containing enable or disable aer flag. |
| 3080 | * @count: unused variable. | 3178 | * @count: unused variable. |
| 3081 | * | 3179 | * |
| 3082 | * Description: | 3180 | * Description: |
| @@ -3160,7 +3258,7 @@ lpfc_param_show(aer_support) | |||
| 3160 | /** | 3258 | /** |
| 3161 | * lpfc_aer_support_init - Set the initial adapters aer support flag | 3259 | * lpfc_aer_support_init - Set the initial adapters aer support flag |
| 3162 | * @phba: lpfc_hba pointer. | 3260 | * @phba: lpfc_hba pointer. |
| 3163 | * @val: link speed value. | 3261 | * @val: enable aer or disable aer flag. |
| 3164 | * | 3262 | * |
| 3165 | * Description: | 3263 | * Description: |
| 3166 | * If val is in a valid range [0,1], then set the adapter's initial | 3264 | * If val is in a valid range [0,1], then set the adapter's initial |
| @@ -3199,7 +3297,7 @@ static DEVICE_ATTR(lpfc_aer_support, S_IRUGO | S_IWUSR, | |||
| 3199 | * lpfc_aer_cleanup_state - Clean up aer state to the aer enabled device | 3297 | * lpfc_aer_cleanup_state - Clean up aer state to the aer enabled device |
| 3200 | * @dev: class device that is converted into a Scsi_host. | 3298 | * @dev: class device that is converted into a Scsi_host. |
| 3201 | * @attr: device attribute, not used. | 3299 | * @attr: device attribute, not used. |
| 3202 | * @buf: containing the string "selective". | 3300 | * @buf: containing flag 1 for aer cleanup state. |
| 3203 | * @count: unused variable. | 3301 | * @count: unused variable. |
| 3204 | * | 3302 | * |
| 3205 | * Description: | 3303 | * Description: |
| @@ -3242,6 +3340,136 @@ lpfc_aer_cleanup_state(struct device *dev, struct device_attribute *attr, | |||
| 3242 | static DEVICE_ATTR(lpfc_aer_state_cleanup, S_IWUSR, NULL, | 3340 | static DEVICE_ATTR(lpfc_aer_state_cleanup, S_IWUSR, NULL, |
| 3243 | lpfc_aer_cleanup_state); | 3341 | lpfc_aer_cleanup_state); |
| 3244 | 3342 | ||
| 3343 | /** | ||
| 3344 | * lpfc_sriov_nr_virtfn_store - Enable the adapter for sr-iov virtual functions | ||
| 3345 | * | ||
| 3346 | * @dev: class device that is converted into a Scsi_host. | ||
| 3347 | * @attr: device attribute, not used. | ||
| 3348 | * @buf: containing the string the number of vfs to be enabled. | ||
| 3349 | * @count: unused variable. | ||
| 3350 | * | ||
| 3351 | * Description: | ||
| 3352 | * When this api is called either through user sysfs, the driver shall | ||
| 3353 | * try to enable or disable SR-IOV virtual functions according to the | ||
| 3354 | * following: | ||
| 3355 | * | ||
| 3356 | * If zero virtual function has been enabled to the physical function, | ||
| 3357 | * the driver shall invoke the pci enable virtual function api trying | ||
| 3358 | * to enable the virtual functions. If the nr_vfn provided is greater | ||
| 3359 | * than the maximum supported, the maximum virtual function number will | ||
| 3360 | * be used for invoking the api; otherwise, the nr_vfn provided shall | ||
| 3361 | * be used for invoking the api. If the api call returned success, the | ||
| 3362 | * actual number of virtual functions enabled will be set to the driver | ||
| 3363 | * cfg_sriov_nr_virtfn; otherwise, -EINVAL shall be returned and driver | ||
| 3364 | * cfg_sriov_nr_virtfn remains zero. | ||
| 3365 | * | ||
| 3366 | * If none-zero virtual functions have already been enabled to the | ||
| 3367 | * physical function, as reflected by the driver's cfg_sriov_nr_virtfn, | ||
| 3368 | * -EINVAL will be returned and the driver does nothing; | ||
| 3369 | * | ||
| 3370 | * If the nr_vfn provided is zero and none-zero virtual functions have | ||
| 3371 | * been enabled, as indicated by the driver's cfg_sriov_nr_virtfn, the | ||
| 3372 | * disabling virtual function api shall be invoded to disable all the | ||
| 3373 | * virtual functions and driver's cfg_sriov_nr_virtfn shall be set to | ||
| 3374 | * zero. Otherwise, if zero virtual function has been enabled, do | ||
| 3375 | * nothing. | ||
| 3376 | * | ||
| 3377 | * Returns: | ||
| 3378 | * length of the buf on success if val is in range the intended mode | ||
| 3379 | * is supported. | ||
| 3380 | * -EINVAL if val out of range or intended mode is not supported. | ||
| 3381 | **/ | ||
| 3382 | static ssize_t | ||
| 3383 | lpfc_sriov_nr_virtfn_store(struct device *dev, struct device_attribute *attr, | ||
| 3384 | const char *buf, size_t count) | ||
| 3385 | { | ||
| 3386 | struct Scsi_Host *shost = class_to_shost(dev); | ||
| 3387 | struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata; | ||
| 3388 | struct lpfc_hba *phba = vport->phba; | ||
| 3389 | struct pci_dev *pdev = phba->pcidev; | ||
| 3390 | int val = 0, rc = -EINVAL; | ||
| 3391 | |||
| 3392 | /* Sanity check on user data */ | ||
| 3393 | if (!isdigit(buf[0])) | ||
| 3394 | return -EINVAL; | ||
| 3395 | if (sscanf(buf, "%i", &val) != 1) | ||
| 3396 | return -EINVAL; | ||
| 3397 | if (val < 0) | ||
| 3398 | return -EINVAL; | ||
| 3399 | |||
| 3400 | /* Request disabling virtual functions */ | ||
| 3401 | if (val == 0) { | ||
| 3402 | if (phba->cfg_sriov_nr_virtfn > 0) { | ||
| 3403 | pci_disable_sriov(pdev); | ||
| 3404 | phba->cfg_sriov_nr_virtfn = 0; | ||
| 3405 | } | ||
| 3406 | return strlen(buf); | ||
| 3407 | } | ||
| 3408 | |||
| 3409 | /* Request enabling virtual functions */ | ||
| 3410 | if (phba->cfg_sriov_nr_virtfn > 0) { | ||
| 3411 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
| 3412 | "3018 There are %d virtual functions " | ||
| 3413 | "enabled on physical function.\n", | ||
| 3414 | phba->cfg_sriov_nr_virtfn); | ||
| 3415 | return -EEXIST; | ||
| 3416 | } | ||
| 3417 | |||
| 3418 | if (val <= LPFC_MAX_VFN_PER_PFN) | ||
| 3419 | phba->cfg_sriov_nr_virtfn = val; | ||
| 3420 | else { | ||
| 3421 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
| 3422 | "3019 Enabling %d virtual functions is not " | ||
| 3423 | "allowed.\n", val); | ||
| 3424 | return -EINVAL; | ||
| 3425 | } | ||
| 3426 | |||
| 3427 | rc = lpfc_sli_probe_sriov_nr_virtfn(phba, phba->cfg_sriov_nr_virtfn); | ||
| 3428 | if (rc) { | ||
| 3429 | phba->cfg_sriov_nr_virtfn = 0; | ||
| 3430 | rc = -EPERM; | ||
| 3431 | } else | ||
| 3432 | rc = strlen(buf); | ||
| 3433 | |||
| 3434 | return rc; | ||
| 3435 | } | ||
| 3436 | |||
| 3437 | static int lpfc_sriov_nr_virtfn = LPFC_DEF_VFN_PER_PFN; | ||
| 3438 | module_param(lpfc_sriov_nr_virtfn, int, S_IRUGO|S_IWUSR); | ||
| 3439 | MODULE_PARM_DESC(lpfc_sriov_nr_virtfn, "Enable PCIe device SR-IOV virtual fn"); | ||
| 3440 | lpfc_param_show(sriov_nr_virtfn) | ||
| 3441 | |||
| 3442 | /** | ||
| 3443 | * lpfc_sriov_nr_virtfn_init - Set the initial sr-iov virtual function enable | ||
| 3444 | * @phba: lpfc_hba pointer. | ||
| 3445 | * @val: link speed value. | ||
| 3446 | * | ||
| 3447 | * Description: | ||
| 3448 | * If val is in a valid range [0,255], then set the adapter's initial | ||
| 3449 | * cfg_sriov_nr_virtfn field. If it's greater than the maximum, the maximum | ||
| 3450 | * number shall be used instead. It will be up to the driver's probe_one | ||
| 3451 | * routine to determine whether the device's SR-IOV is supported or not. | ||
| 3452 | * | ||
| 3453 | * Returns: | ||
| 3454 | * zero if val saved. | ||
| 3455 | * -EINVAL val out of range | ||
| 3456 | **/ | ||
| 3457 | static int | ||
| 3458 | lpfc_sriov_nr_virtfn_init(struct lpfc_hba *phba, int val) | ||
| 3459 | { | ||
| 3460 | if (val >= 0 && val <= LPFC_MAX_VFN_PER_PFN) { | ||
| 3461 | phba->cfg_sriov_nr_virtfn = val; | ||
| 3462 | return 0; | ||
| 3463 | } | ||
| 3464 | |||
| 3465 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
| 3466 | "3017 Enabling %d virtual functions is not " | ||
| 3467 | "allowed.\n", val); | ||
| 3468 | return -EINVAL; | ||
| 3469 | } | ||
| 3470 | static DEVICE_ATTR(lpfc_sriov_nr_virtfn, S_IRUGO | S_IWUSR, | ||
| 3471 | lpfc_sriov_nr_virtfn_show, lpfc_sriov_nr_virtfn_store); | ||
| 3472 | |||
| 3245 | /* | 3473 | /* |
| 3246 | # lpfc_fcp_class: Determines FC class to use for the FCP protocol. | 3474 | # lpfc_fcp_class: Determines FC class to use for the FCP protocol. |
| 3247 | # Value range is [2,3]. Default value is 3. | 3475 | # Value range is [2,3]. Default value is 3. |
| @@ -3559,6 +3787,7 @@ struct device_attribute *lpfc_hba_attrs[] = { | |||
| 3559 | &dev_attr_lpfc_prot_sg_seg_cnt, | 3787 | &dev_attr_lpfc_prot_sg_seg_cnt, |
| 3560 | &dev_attr_lpfc_aer_support, | 3788 | &dev_attr_lpfc_aer_support, |
| 3561 | &dev_attr_lpfc_aer_state_cleanup, | 3789 | &dev_attr_lpfc_aer_state_cleanup, |
| 3790 | &dev_attr_lpfc_sriov_nr_virtfn, | ||
| 3562 | &dev_attr_lpfc_suppress_link_up, | 3791 | &dev_attr_lpfc_suppress_link_up, |
| 3563 | &dev_attr_lpfc_iocb_cnt, | 3792 | &dev_attr_lpfc_iocb_cnt, |
| 3564 | &dev_attr_iocb_hw, | 3793 | &dev_attr_iocb_hw, |
| @@ -3567,6 +3796,7 @@ struct device_attribute *lpfc_hba_attrs[] = { | |||
| 3567 | &dev_attr_lpfc_fips_level, | 3796 | &dev_attr_lpfc_fips_level, |
| 3568 | &dev_attr_lpfc_fips_rev, | 3797 | &dev_attr_lpfc_fips_rev, |
| 3569 | &dev_attr_lpfc_dss, | 3798 | &dev_attr_lpfc_dss, |
| 3799 | &dev_attr_lpfc_sriov_hw_max_virtfn, | ||
| 3570 | NULL, | 3800 | NULL, |
| 3571 | }; | 3801 | }; |
| 3572 | 3802 | ||
| @@ -4767,6 +4997,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) | |||
| 4767 | lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth); | 4997 | lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth); |
| 4768 | lpfc_hba_log_verbose_init(phba, lpfc_log_verbose); | 4998 | lpfc_hba_log_verbose_init(phba, lpfc_log_verbose); |
| 4769 | lpfc_aer_support_init(phba, lpfc_aer_support); | 4999 | lpfc_aer_support_init(phba, lpfc_aer_support); |
| 5000 | lpfc_sriov_nr_virtfn_init(phba, lpfc_sriov_nr_virtfn); | ||
| 4770 | lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up); | 5001 | lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up); |
| 4771 | lpfc_iocb_cnt_init(phba, lpfc_iocb_cnt); | 5002 | lpfc_iocb_cnt_init(phba, lpfc_iocb_cnt); |
| 4772 | phba->cfg_enable_dss = 1; | 5003 | phba->cfg_enable_dss = 1; |
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index eb02016a21b5..3b9a6152b7f9 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
| @@ -430,3 +430,5 @@ void lpfc_cleanup_wt_rrqs(struct lpfc_hba *); | |||
| 430 | void lpfc_cleanup_vports_rrqs(struct lpfc_vport *, struct lpfc_nodelist *); | 430 | void lpfc_cleanup_vports_rrqs(struct lpfc_vport *, struct lpfc_nodelist *); |
| 431 | struct lpfc_node_rrq *lpfc_get_active_rrq(struct lpfc_vport *, uint16_t, | 431 | struct lpfc_node_rrq *lpfc_get_active_rrq(struct lpfc_vport *, uint16_t, |
| 432 | uint32_t); | 432 | uint32_t); |
| 433 | /* functions to support SR-IOV */ | ||
| 434 | int lpfc_sli_probe_sriov_nr_virtfn(struct lpfc_hba *, int); | ||
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 6aa53aca23e9..bb3af9fabd7e 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h | |||
| @@ -903,6 +903,8 @@ struct RRQ { /* Structure is in Big Endian format */ | |||
| 903 | #define rrq_rxid_WORD rrq_exchg | 903 | #define rrq_rxid_WORD rrq_exchg |
| 904 | }; | 904 | }; |
| 905 | 905 | ||
| 906 | #define LPFC_MAX_VFN_PER_PFN 255 /* Maximum VFs allowed per ARI */ | ||
| 907 | #define LPFC_DEF_VFN_PER_PFN 0 /* Default VFs due to platform limitation*/ | ||
| 906 | 908 | ||
| 907 | struct RTV_RSP { /* Structure is in Big Endian format */ | 909 | struct RTV_RSP { /* Structure is in Big Endian format */ |
| 908 | uint32_t ratov; | 910 | uint32_t ratov; |
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index ca7c1dd61938..115915d4a60a 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
| @@ -758,6 +758,12 @@ union lpfc_sli4_cfg_shdr { | |||
| 758 | #define lpfc_mbox_hdr_version_SHIFT 0 | 758 | #define lpfc_mbox_hdr_version_SHIFT 0 |
| 759 | #define lpfc_mbox_hdr_version_MASK 0x000000FF | 759 | #define lpfc_mbox_hdr_version_MASK 0x000000FF |
| 760 | #define lpfc_mbox_hdr_version_WORD word9 | 760 | #define lpfc_mbox_hdr_version_WORD word9 |
| 761 | #define lpfc_mbox_hdr_pf_num_SHIFT 16 | ||
| 762 | #define lpfc_mbox_hdr_pf_num_MASK 0x000000FF | ||
| 763 | #define lpfc_mbox_hdr_pf_num_WORD word9 | ||
| 764 | #define lpfc_mbox_hdr_vh_num_SHIFT 24 | ||
| 765 | #define lpfc_mbox_hdr_vh_num_MASK 0x000000FF | ||
| 766 | #define lpfc_mbox_hdr_vh_num_WORD word9 | ||
| 761 | #define LPFC_Q_CREATE_VERSION_2 2 | 767 | #define LPFC_Q_CREATE_VERSION_2 2 |
| 762 | #define LPFC_Q_CREATE_VERSION_1 1 | 768 | #define LPFC_Q_CREATE_VERSION_1 1 |
| 763 | #define LPFC_Q_CREATE_VERSION_0 0 | 769 | #define LPFC_Q_CREATE_VERSION_0 0 |
| @@ -813,6 +819,8 @@ struct mbox_header { | |||
| 813 | #define LPFC_MBOX_OPCODE_QUERY_FW_CFG 0x3A | 819 | #define LPFC_MBOX_OPCODE_QUERY_FW_CFG 0x3A |
| 814 | #define LPFC_MBOX_OPCODE_FUNCTION_RESET 0x3D | 820 | #define LPFC_MBOX_OPCODE_FUNCTION_RESET 0x3D |
| 815 | #define LPFC_MBOX_OPCODE_MQ_CREATE_EXT 0x5A | 821 | #define LPFC_MBOX_OPCODE_MQ_CREATE_EXT 0x5A |
| 822 | #define LPFC_MBOX_OPCODE_GET_FUNCTION_CONFIG 0xA0 | ||
| 823 | #define LPFC_MBOX_OPCODE_GET_PROFILE_CONFIG 0xA4 | ||
| 816 | #define LPFC_MBOX_OPCODE_GET_SLI4_PARAMETERS 0xB5 | 824 | #define LPFC_MBOX_OPCODE_GET_SLI4_PARAMETERS 0xB5 |
| 817 | 825 | ||
| 818 | /* FCoE Opcodes */ | 826 | /* FCoE Opcodes */ |
| @@ -2217,6 +2225,145 @@ struct lpfc_mbx_get_sli4_parameters { | |||
| 2217 | struct lpfc_sli4_parameters sli4_parameters; | 2225 | struct lpfc_sli4_parameters sli4_parameters; |
| 2218 | }; | 2226 | }; |
| 2219 | 2227 | ||
| 2228 | struct lpfc_rscr_desc_generic { | ||
| 2229 | #define LPFC_RSRC_DESC_WSIZE 18 | ||
| 2230 | uint32_t desc[LPFC_RSRC_DESC_WSIZE]; | ||
| 2231 | }; | ||
| 2232 | |||
| 2233 | struct lpfc_rsrc_desc_pcie { | ||
| 2234 | uint32_t word0; | ||
| 2235 | #define lpfc_rsrc_desc_pcie_type_SHIFT 0 | ||
| 2236 | #define lpfc_rsrc_desc_pcie_type_MASK 0x000000ff | ||
| 2237 | #define lpfc_rsrc_desc_pcie_type_WORD word0 | ||
| 2238 | #define LPFC_RSRC_DESC_TYPE_PCIE 0x40 | ||
| 2239 | uint32_t word1; | ||
| 2240 | #define lpfc_rsrc_desc_pcie_pfnum_SHIFT 0 | ||
| 2241 | #define lpfc_rsrc_desc_pcie_pfnum_MASK 0x000000ff | ||
| 2242 | #define lpfc_rsrc_desc_pcie_pfnum_WORD word1 | ||
| 2243 | uint32_t reserved; | ||
| 2244 | uint32_t word3; | ||
| 2245 | #define lpfc_rsrc_desc_pcie_sriov_sta_SHIFT 0 | ||
| 2246 | #define lpfc_rsrc_desc_pcie_sriov_sta_MASK 0x000000ff | ||
| 2247 | #define lpfc_rsrc_desc_pcie_sriov_sta_WORD word3 | ||
| 2248 | #define lpfc_rsrc_desc_pcie_pf_sta_SHIFT 8 | ||
| 2249 | #define lpfc_rsrc_desc_pcie_pf_sta_MASK 0x000000ff | ||
| 2250 | #define lpfc_rsrc_desc_pcie_pf_sta_WORD word3 | ||
| 2251 | #define lpfc_rsrc_desc_pcie_pf_type_SHIFT 16 | ||
| 2252 | #define lpfc_rsrc_desc_pcie_pf_type_MASK 0x000000ff | ||
| 2253 | #define lpfc_rsrc_desc_pcie_pf_type_WORD word3 | ||
| 2254 | uint32_t word4; | ||
| 2255 | #define lpfc_rsrc_desc_pcie_nr_virtfn_SHIFT 0 | ||
| 2256 | #define lpfc_rsrc_desc_pcie_nr_virtfn_MASK 0x0000ffff | ||
| 2257 | #define lpfc_rsrc_desc_pcie_nr_virtfn_WORD word4 | ||
| 2258 | }; | ||
| 2259 | |||
| 2260 | struct lpfc_rsrc_desc_fcfcoe { | ||
| 2261 | uint32_t word0; | ||
| 2262 | #define lpfc_rsrc_desc_fcfcoe_type_SHIFT 0 | ||
| 2263 | #define lpfc_rsrc_desc_fcfcoe_type_MASK 0x000000ff | ||
| 2264 | #define lpfc_rsrc_desc_fcfcoe_type_WORD word0 | ||
| 2265 | #define LPFC_RSRC_DESC_TYPE_FCFCOE 0x43 | ||
| 2266 | uint32_t word1; | ||
| 2267 | #define lpfc_rsrc_desc_fcfcoe_vfnum_SHIFT 0 | ||
| 2268 | #define lpfc_rsrc_desc_fcfcoe_vfnum_MASK 0x000000ff | ||
| 2269 | #define lpfc_rsrc_desc_fcfcoe_vfnum_WORD word1 | ||
| 2270 | #define lpfc_rsrc_desc_fcfcoe_pfnum_SHIFT 16 | ||
| 2271 | #define lpfc_rsrc_desc_fcfcoe_pfnum_MASK 0x000007ff | ||
| 2272 | #define lpfc_rsrc_desc_fcfcoe_pfnum_WORD word1 | ||
| 2273 | uint32_t word2; | ||
| 2274 | #define lpfc_rsrc_desc_fcfcoe_rpi_cnt_SHIFT 0 | ||
| 2275 | #define lpfc_rsrc_desc_fcfcoe_rpi_cnt_MASK 0x0000ffff | ||
| 2276 | #define lpfc_rsrc_desc_fcfcoe_rpi_cnt_WORD word2 | ||
| 2277 | #define lpfc_rsrc_desc_fcfcoe_xri_cnt_SHIFT 16 | ||
| 2278 | #define lpfc_rsrc_desc_fcfcoe_xri_cnt_MASK 0x0000ffff | ||
| 2279 | #define lpfc_rsrc_desc_fcfcoe_xri_cnt_WORD word2 | ||
| 2280 | uint32_t word3; | ||
| 2281 | #define lpfc_rsrc_desc_fcfcoe_wq_cnt_SHIFT 0 | ||
| 2282 | #define lpfc_rsrc_desc_fcfcoe_wq_cnt_MASK 0x0000ffff | ||
| 2283 | #define lpfc_rsrc_desc_fcfcoe_wq_cnt_WORD word3 | ||
| 2284 | #define lpfc_rsrc_desc_fcfcoe_rq_cnt_SHIFT 16 | ||
| 2285 | #define lpfc_rsrc_desc_fcfcoe_rq_cnt_MASK 0x0000ffff | ||
| 2286 | #define lpfc_rsrc_desc_fcfcoe_rq_cnt_WORD word3 | ||
| 2287 | uint32_t word4; | ||
| 2288 | #define lpfc_rsrc_desc_fcfcoe_cq_cnt_SHIFT 0 | ||
| 2289 | #define lpfc_rsrc_desc_fcfcoe_cq_cnt_MASK 0x0000ffff | ||
| 2290 | #define lpfc_rsrc_desc_fcfcoe_cq_cnt_WORD word4 | ||
| 2291 | #define lpfc_rsrc_desc_fcfcoe_vpi_cnt_SHIFT 16 | ||
| 2292 | #define lpfc_rsrc_desc_fcfcoe_vpi_cnt_MASK 0x0000ffff | ||
| 2293 | #define lpfc_rsrc_desc_fcfcoe_vpi_cnt_WORD word4 | ||
| 2294 | uint32_t word5; | ||
| 2295 | #define lpfc_rsrc_desc_fcfcoe_fcfi_cnt_SHIFT 0 | ||
| 2296 | #define lpfc_rsrc_desc_fcfcoe_fcfi_cnt_MASK 0x0000ffff | ||
| 2297 | #define lpfc_rsrc_desc_fcfcoe_fcfi_cnt_WORD word5 | ||
| 2298 | #define lpfc_rsrc_desc_fcfcoe_vfi_cnt_SHIFT 16 | ||
| 2299 | #define lpfc_rsrc_desc_fcfcoe_vfi_cnt_MASK 0x0000ffff | ||
| 2300 | #define lpfc_rsrc_desc_fcfcoe_vfi_cnt_WORD word5 | ||
| 2301 | uint32_t word6; | ||
| 2302 | uint32_t word7; | ||
| 2303 | uint32_t word8; | ||
| 2304 | uint32_t word9; | ||
| 2305 | uint32_t word10; | ||
| 2306 | uint32_t word11; | ||
| 2307 | uint32_t word12; | ||
| 2308 | uint32_t word13; | ||
| 2309 | #define lpfc_rsrc_desc_fcfcoe_lnk_nr_SHIFT 0 | ||
| 2310 | #define lpfc_rsrc_desc_fcfcoe_lnk_nr_MASK 0x0000003f | ||
| 2311 | #define lpfc_rsrc_desc_fcfcoe_lnk_nr_WORD word13 | ||
| 2312 | #define lpfc_rsrc_desc_fcfcoe_lnk_tp_SHIFT 6 | ||
| 2313 | #define lpfc_rsrc_desc_fcfcoe_lnk_tp_MASK 0x00000003 | ||
| 2314 | #define lpfc_rsrc_desc_fcfcoe_lnk_tp_WORD word13 | ||
| 2315 | #define lpfc_rsrc_desc_fcfcoe_lmc_SHIFT 8 | ||
| 2316 | #define lpfc_rsrc_desc_fcfcoe_lmc_MASK 0x00000001 | ||
| 2317 | #define lpfc_rsrc_desc_fcfcoe_lmc_WORD word13 | ||
| 2318 | #define lpfc_rsrc_desc_fcfcoe_lld_SHIFT 9 | ||
| 2319 | #define lpfc_rsrc_desc_fcfcoe_lld_MASK 0x00000001 | ||
| 2320 | #define lpfc_rsrc_desc_fcfcoe_lld_WORD word13 | ||
| 2321 | #define lpfc_rsrc_desc_fcfcoe_eq_cnt_SHIFT 16 | ||
| 2322 | #define lpfc_rsrc_desc_fcfcoe_eq_cnt_MASK 0x0000ffff | ||
| 2323 | #define lpfc_rsrc_desc_fcfcoe_eq_cnt_WORD word13 | ||
| 2324 | }; | ||
| 2325 | |||
| 2326 | struct lpfc_func_cfg { | ||
| 2327 | #define LPFC_RSRC_DESC_MAX_NUM 2 | ||
| 2328 | uint32_t rsrc_desc_count; | ||
| 2329 | struct lpfc_rscr_desc_generic desc[LPFC_RSRC_DESC_MAX_NUM]; | ||
| 2330 | }; | ||
| 2331 | |||
| 2332 | struct lpfc_mbx_get_func_cfg { | ||
| 2333 | struct mbox_header header; | ||
| 2334 | #define LPFC_CFG_TYPE_PERSISTENT_OVERRIDE 0x0 | ||
| 2335 | #define LPFC_CFG_TYPE_FACTURY_DEFAULT 0x1 | ||
| 2336 | #define LPFC_CFG_TYPE_CURRENT_ACTIVE 0x2 | ||
| 2337 | struct lpfc_func_cfg func_cfg; | ||
| 2338 | }; | ||
| 2339 | |||
| 2340 | struct lpfc_prof_cfg { | ||
| 2341 | #define LPFC_RSRC_DESC_MAX_NUM 2 | ||
| 2342 | uint32_t rsrc_desc_count; | ||
| 2343 | struct lpfc_rscr_desc_generic desc[LPFC_RSRC_DESC_MAX_NUM]; | ||
| 2344 | }; | ||
| 2345 | |||
| 2346 | struct lpfc_mbx_get_prof_cfg { | ||
| 2347 | struct mbox_header header; | ||
| 2348 | #define LPFC_CFG_TYPE_PERSISTENT_OVERRIDE 0x0 | ||
| 2349 | #define LPFC_CFG_TYPE_FACTURY_DEFAULT 0x1 | ||
| 2350 | #define LPFC_CFG_TYPE_CURRENT_ACTIVE 0x2 | ||
| 2351 | union { | ||
| 2352 | struct { | ||
| 2353 | uint32_t word10; | ||
| 2354 | #define lpfc_mbx_get_prof_cfg_prof_id_SHIFT 0 | ||
| 2355 | #define lpfc_mbx_get_prof_cfg_prof_id_MASK 0x000000ff | ||
| 2356 | #define lpfc_mbx_get_prof_cfg_prof_id_WORD word10 | ||
| 2357 | #define lpfc_mbx_get_prof_cfg_prof_tp_SHIFT 8 | ||
| 2358 | #define lpfc_mbx_get_prof_cfg_prof_tp_MASK 0x00000003 | ||
| 2359 | #define lpfc_mbx_get_prof_cfg_prof_tp_WORD word10 | ||
| 2360 | } request; | ||
| 2361 | struct { | ||
| 2362 | struct lpfc_prof_cfg prof_cfg; | ||
| 2363 | } response; | ||
| 2364 | } u; | ||
| 2365 | }; | ||
| 2366 | |||
| 2220 | /* Mailbox Completion Queue Error Messages */ | 2367 | /* Mailbox Completion Queue Error Messages */ |
| 2221 | #define MB_CQE_STATUS_SUCCESS 0x0 | 2368 | #define MB_CQE_STATUS_SUCCESS 0x0 |
| 2222 | #define MB_CQE_STATUS_INSUFFICIENT_PRIVILEGES 0x1 | 2369 | #define MB_CQE_STATUS_INSUFFICIENT_PRIVILEGES 0x1 |
| @@ -2271,6 +2418,8 @@ struct lpfc_mqe { | |||
| 2271 | struct lpfc_mbx_supp_pages supp_pages; | 2418 | struct lpfc_mbx_supp_pages supp_pages; |
| 2272 | struct lpfc_mbx_pc_sli4_params sli4_params; | 2419 | struct lpfc_mbx_pc_sli4_params sli4_params; |
| 2273 | struct lpfc_mbx_get_sli4_parameters get_sli4_parameters; | 2420 | struct lpfc_mbx_get_sli4_parameters get_sli4_parameters; |
| 2421 | struct lpfc_mbx_get_func_cfg get_func_cfg; | ||
| 2422 | struct lpfc_mbx_get_prof_cfg get_prof_cfg; | ||
| 2274 | struct lpfc_mbx_nop nop; | 2423 | struct lpfc_mbx_nop nop; |
| 2275 | } un; | 2424 | } un; |
| 2276 | }; | 2425 | }; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 16b4da4530b1..e81912cd257e 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
| @@ -4034,6 +4034,36 @@ lpfc_reset_hba(struct lpfc_hba *phba) | |||
| 4034 | } | 4034 | } |
| 4035 | 4035 | ||
| 4036 | /** | 4036 | /** |
| 4037 | * lpfc_sli_probe_sriov_nr_virtfn - Enable a number of sr-iov virtual functions | ||
| 4038 | * @phba: pointer to lpfc hba data structure. | ||
| 4039 | * @nr_vfn: number of virtual functions to be enabled. | ||
| 4040 | * | ||
| 4041 | * This function enables the PCI SR-IOV virtual functions to a physical | ||
| 4042 | * function. It invokes the PCI SR-IOV api with the @nr_vfn provided to | ||
| 4043 | * enable the number of virtual functions to the physical function. As | ||
| 4044 | * not all devices support SR-IOV, the return code from the pci_enable_sriov() | ||
| 4045 | * API call does not considered as an error condition for most of the device. | ||
| 4046 | **/ | ||
| 4047 | int | ||
| 4048 | lpfc_sli_probe_sriov_nr_virtfn(struct lpfc_hba *phba, int nr_vfn) | ||
| 4049 | { | ||
| 4050 | struct pci_dev *pdev = phba->pcidev; | ||
| 4051 | int rc; | ||
| 4052 | |||
| 4053 | rc = pci_enable_sriov(pdev, nr_vfn); | ||
| 4054 | if (rc) { | ||
| 4055 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | ||
| 4056 | "2806 Failed to enable sriov on this device " | ||
| 4057 | "with vfn number nr_vf:%d, rc:%d\n", | ||
| 4058 | nr_vfn, rc); | ||
| 4059 | } else | ||
| 4060 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | ||
| 4061 | "2807 Successful enable sriov on this device " | ||
| 4062 | "with vfn number nr_vf:%d\n", nr_vfn); | ||
| 4063 | return rc; | ||
| 4064 | } | ||
| 4065 | |||
| 4066 | /** | ||
| 4037 | * lpfc_sli_driver_resource_setup - Setup driver internal resources for SLI3 dev. | 4067 | * lpfc_sli_driver_resource_setup - Setup driver internal resources for SLI3 dev. |
| 4038 | * @phba: pointer to lpfc hba data structure. | 4068 | * @phba: pointer to lpfc hba data structure. |
| 4039 | * | 4069 | * |
| @@ -4048,6 +4078,7 @@ static int | |||
| 4048 | lpfc_sli_driver_resource_setup(struct lpfc_hba *phba) | 4078 | lpfc_sli_driver_resource_setup(struct lpfc_hba *phba) |
| 4049 | { | 4079 | { |
| 4050 | struct lpfc_sli *psli; | 4080 | struct lpfc_sli *psli; |
| 4081 | int rc; | ||
| 4051 | 4082 | ||
| 4052 | /* | 4083 | /* |
| 4053 | * Initialize timers used by driver | 4084 | * Initialize timers used by driver |
| @@ -4122,6 +4153,23 @@ lpfc_sli_driver_resource_setup(struct lpfc_hba *phba) | |||
| 4122 | if (lpfc_mem_alloc(phba, BPL_ALIGN_SZ)) | 4153 | if (lpfc_mem_alloc(phba, BPL_ALIGN_SZ)) |
| 4123 | return -ENOMEM; | 4154 | return -ENOMEM; |
| 4124 | 4155 | ||
| 4156 | /* | ||
| 4157 | * Enable sr-iov virtual functions if supported and configured | ||
| 4158 | * through the module parameter. | ||
| 4159 | */ | ||
| 4160 | if (phba->cfg_sriov_nr_virtfn > 0) { | ||
| 4161 | rc = lpfc_sli_probe_sriov_nr_virtfn(phba, | ||
| 4162 | phba->cfg_sriov_nr_virtfn); | ||
| 4163 | if (rc) { | ||
| 4164 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | ||
| 4165 | "2808 Requested number of SR-IOV " | ||
| 4166 | "virtual functions (%d) is not " | ||
| 4167 | "supported\n", | ||
| 4168 | phba->cfg_sriov_nr_virtfn); | ||
| 4169 | phba->cfg_sriov_nr_virtfn = 0; | ||
| 4170 | } | ||
| 4171 | } | ||
| 4172 | |||
| 4125 | return 0; | 4173 | return 0; |
| 4126 | } | 4174 | } |
| 4127 | 4175 | ||
| @@ -4427,6 +4475,23 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
| 4427 | goto out_free_fcp_eq_hdl; | 4475 | goto out_free_fcp_eq_hdl; |
| 4428 | } | 4476 | } |
| 4429 | 4477 | ||
| 4478 | /* | ||
| 4479 | * Enable sr-iov virtual functions if supported and configured | ||
| 4480 | * through the module parameter. | ||
| 4481 | */ | ||
| 4482 | if (phba->cfg_sriov_nr_virtfn > 0) { | ||
| 4483 | rc = lpfc_sli_probe_sriov_nr_virtfn(phba, | ||
| 4484 | phba->cfg_sriov_nr_virtfn); | ||
| 4485 | if (rc) { | ||
| 4486 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | ||
| 4487 | "3020 Requested number of SR-IOV " | ||
| 4488 | "virtual functions (%d) is not " | ||
| 4489 | "supported\n", | ||
| 4490 | phba->cfg_sriov_nr_virtfn); | ||
| 4491 | phba->cfg_sriov_nr_virtfn = 0; | ||
| 4492 | } | ||
| 4493 | } | ||
| 4494 | |||
| 4430 | return rc; | 4495 | return rc; |
| 4431 | 4496 | ||
| 4432 | out_free_fcp_eq_hdl: | 4497 | out_free_fcp_eq_hdl: |
| @@ -5780,7 +5845,12 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) | |||
| 5780 | { | 5845 | { |
| 5781 | LPFC_MBOXQ_t *pmb; | 5846 | LPFC_MBOXQ_t *pmb; |
| 5782 | struct lpfc_mbx_read_config *rd_config; | 5847 | struct lpfc_mbx_read_config *rd_config; |
| 5783 | uint32_t rc = 0; | 5848 | union lpfc_sli4_cfg_shdr *shdr; |
| 5849 | uint32_t shdr_status, shdr_add_status; | ||
| 5850 | struct lpfc_mbx_get_func_cfg *get_func_cfg; | ||
| 5851 | struct lpfc_rsrc_desc_fcfcoe *desc; | ||
| 5852 | uint32_t desc_count; | ||
| 5853 | int length, i, rc = 0; | ||
| 5784 | 5854 | ||
| 5785 | pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 5855 | pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
| 5786 | if (!pmb) { | 5856 | if (!pmb) { |
| @@ -5855,7 +5925,9 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) | |||
| 5855 | phba->sli4_hba.max_cfg_param.fcfi_base, | 5925 | phba->sli4_hba.max_cfg_param.fcfi_base, |
| 5856 | phba->sli4_hba.max_cfg_param.max_fcfi); | 5926 | phba->sli4_hba.max_cfg_param.max_fcfi); |
| 5857 | } | 5927 | } |
| 5858 | mempool_free(pmb, phba->mbox_mem_pool); | 5928 | |
| 5929 | if (rc) | ||
| 5930 | goto read_cfg_out; | ||
| 5859 | 5931 | ||
| 5860 | /* Reset the DFT_HBA_Q_DEPTH to the max xri */ | 5932 | /* Reset the DFT_HBA_Q_DEPTH to the max xri */ |
| 5861 | if (phba->cfg_hba_queue_depth > | 5933 | if (phba->cfg_hba_queue_depth > |
| @@ -5864,6 +5936,65 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) | |||
| 5864 | phba->cfg_hba_queue_depth = | 5936 | phba->cfg_hba_queue_depth = |
| 5865 | phba->sli4_hba.max_cfg_param.max_xri - | 5937 | phba->sli4_hba.max_cfg_param.max_xri - |
| 5866 | lpfc_sli4_get_els_iocb_cnt(phba); | 5938 | lpfc_sli4_get_els_iocb_cnt(phba); |
| 5939 | |||
| 5940 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != | ||
| 5941 | LPFC_SLI_INTF_IF_TYPE_2) | ||
| 5942 | goto read_cfg_out; | ||
| 5943 | |||
| 5944 | /* get the pf# and vf# for SLI4 if_type 2 port */ | ||
| 5945 | length = (sizeof(struct lpfc_mbx_get_func_cfg) - | ||
| 5946 | sizeof(struct lpfc_sli4_cfg_mhdr)); | ||
| 5947 | lpfc_sli4_config(phba, pmb, LPFC_MBOX_SUBSYSTEM_COMMON, | ||
| 5948 | LPFC_MBOX_OPCODE_GET_FUNCTION_CONFIG, | ||
| 5949 | length, LPFC_SLI4_MBX_EMBED); | ||
| 5950 | |||
| 5951 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); | ||
| 5952 | shdr = (union lpfc_sli4_cfg_shdr *) | ||
| 5953 | &pmb->u.mqe.un.sli4_config.header.cfg_shdr; | ||
| 5954 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | ||
| 5955 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); | ||
| 5956 | if (rc || shdr_status || shdr_add_status) { | ||
| 5957 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
| 5958 | "3026 Mailbox failed , mbxCmd x%x " | ||
| 5959 | "GET_FUNCTION_CONFIG, mbxStatus x%x\n", | ||
| 5960 | bf_get(lpfc_mqe_command, &pmb->u.mqe), | ||
| 5961 | bf_get(lpfc_mqe_status, &pmb->u.mqe)); | ||
| 5962 | rc = -EIO; | ||
| 5963 | goto read_cfg_out; | ||
| 5964 | } | ||
| 5965 | |||
| 5966 | /* search for fc_fcoe resrouce descriptor */ | ||
| 5967 | get_func_cfg = &pmb->u.mqe.un.get_func_cfg; | ||
| 5968 | desc_count = get_func_cfg->func_cfg.rsrc_desc_count; | ||
| 5969 | |||
| 5970 | for (i = 0; i < LPFC_RSRC_DESC_MAX_NUM; i++) { | ||
| 5971 | desc = (struct lpfc_rsrc_desc_fcfcoe *) | ||
| 5972 | &get_func_cfg->func_cfg.desc[i]; | ||
| 5973 | if (LPFC_RSRC_DESC_TYPE_FCFCOE == | ||
| 5974 | bf_get(lpfc_rsrc_desc_pcie_type, desc)) { | ||
| 5975 | phba->sli4_hba.iov.pf_number = | ||
| 5976 | bf_get(lpfc_rsrc_desc_fcfcoe_pfnum, desc); | ||
| 5977 | phba->sli4_hba.iov.vf_number = | ||
| 5978 | bf_get(lpfc_rsrc_desc_fcfcoe_vfnum, desc); | ||
| 5979 | break; | ||
| 5980 | } | ||
| 5981 | } | ||
| 5982 | |||
| 5983 | if (i < LPFC_RSRC_DESC_MAX_NUM) | ||
| 5984 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
| 5985 | "3027 GET_FUNCTION_CONFIG: pf_number:%d, " | ||
| 5986 | "vf_number:%d\n", phba->sli4_hba.iov.pf_number, | ||
| 5987 | phba->sli4_hba.iov.vf_number); | ||
| 5988 | else { | ||
| 5989 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
| 5990 | "3028 GET_FUNCTION_CONFIG: failed to find " | ||
| 5991 | "Resrouce Descriptor:x%x\n", | ||
| 5992 | LPFC_RSRC_DESC_TYPE_FCFCOE); | ||
| 5993 | rc = -EIO; | ||
| 5994 | } | ||
| 5995 | |||
| 5996 | read_cfg_out: | ||
| 5997 | mempool_free(pmb, phba->mbox_mem_pool); | ||
| 5867 | return rc; | 5998 | return rc; |
| 5868 | } | 5999 | } |
| 5869 | 6000 | ||
| @@ -7825,6 +7956,7 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba) | |||
| 7825 | { | 7956 | { |
| 7826 | int wait_cnt = 0; | 7957 | int wait_cnt = 0; |
| 7827 | LPFC_MBOXQ_t *mboxq; | 7958 | LPFC_MBOXQ_t *mboxq; |
| 7959 | struct pci_dev *pdev = phba->pcidev; | ||
| 7828 | 7960 | ||
| 7829 | lpfc_stop_hba_timers(phba); | 7961 | lpfc_stop_hba_timers(phba); |
| 7830 | phba->sli4_hba.intr_enable = 0; | 7962 | phba->sli4_hba.intr_enable = 0; |
| @@ -7864,6 +7996,10 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba) | |||
| 7864 | /* Disable PCI subsystem interrupt */ | 7996 | /* Disable PCI subsystem interrupt */ |
| 7865 | lpfc_sli4_disable_intr(phba); | 7997 | lpfc_sli4_disable_intr(phba); |
| 7866 | 7998 | ||
| 7999 | /* Disable SR-IOV if enabled */ | ||
| 8000 | if (phba->cfg_sriov_nr_virtfn) | ||
| 8001 | pci_disable_sriov(pdev); | ||
| 8002 | |||
| 7867 | /* Stop kthread signal shall trigger work_done one more time */ | 8003 | /* Stop kthread signal shall trigger work_done one more time */ |
| 7868 | kthread_stop(phba->worker_thread); | 8004 | kthread_stop(phba->worker_thread); |
| 7869 | 8005 | ||
| @@ -8243,6 +8379,10 @@ lpfc_pci_remove_one_s3(struct pci_dev *pdev) | |||
| 8243 | 8379 | ||
| 8244 | lpfc_debugfs_terminate(vport); | 8380 | lpfc_debugfs_terminate(vport); |
| 8245 | 8381 | ||
| 8382 | /* Disable SR-IOV if enabled */ | ||
| 8383 | if (phba->cfg_sriov_nr_virtfn) | ||
| 8384 | pci_disable_sriov(pdev); | ||
| 8385 | |||
| 8246 | /* Disable interrupt */ | 8386 | /* Disable interrupt */ |
| 8247 | lpfc_sli_disable_intr(phba); | 8387 | lpfc_sli_disable_intr(phba); |
| 8248 | 8388 | ||
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 1a3cbf88f2ce..03d25a9d3bf6 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
| @@ -365,6 +365,11 @@ struct lpfc_pc_sli4_params { | |||
| 365 | uint8_t rqv; | 365 | uint8_t rqv; |
| 366 | }; | 366 | }; |
| 367 | 367 | ||
| 368 | struct lpfc_iov { | ||
| 369 | uint32_t pf_number; | ||
| 370 | uint32_t vf_number; | ||
| 371 | }; | ||
| 372 | |||
| 368 | /* SLI4 HBA data structure entries */ | 373 | /* SLI4 HBA data structure entries */ |
| 369 | struct lpfc_sli4_hba { | 374 | struct lpfc_sli4_hba { |
| 370 | void __iomem *conf_regs_memmap_p; /* Kernel memory mapped address for | 375 | void __iomem *conf_regs_memmap_p; /* Kernel memory mapped address for |
| @@ -467,6 +472,7 @@ struct lpfc_sli4_hba { | |||
| 467 | struct list_head sp_els_xri_aborted_work_queue; | 472 | struct list_head sp_els_xri_aborted_work_queue; |
| 468 | struct list_head sp_unsol_work_queue; | 473 | struct list_head sp_unsol_work_queue; |
| 469 | struct lpfc_sli4_link link_state; | 474 | struct lpfc_sli4_link link_state; |
| 475 | struct lpfc_iov iov; | ||
| 470 | spinlock_t abts_scsi_buf_list_lock; /* list of aborted SCSI IOs */ | 476 | spinlock_t abts_scsi_buf_list_lock; /* list of aborted SCSI IOs */ |
| 471 | spinlock_t abts_sgl_list_lock; /* list of aborted els IOs */ | 477 | spinlock_t abts_sgl_list_lock; /* list of aborted els IOs */ |
| 472 | }; | 478 | }; |
