diff options
author | James Smart <james.smart@emulex.com> | 2011-05-24 11:42:11 -0400 |
---|---|---|
committer | James Bottomley <jbottomley@parallels.com> | 2011-05-26 23:49:36 -0400 |
commit | 912e3acde60b3b9ebf46c5ec5ae6bd01b80132c8 (patch) | |
tree | 2ca2593ff23e61580879e1deb405b2dfc8d92f83 | |
parent | c0c1151276aae83dffbe3f2837a3b1d893894115 (diff) |
[SCSI] lpfc 8.3.24: Add SR-IOV control
Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <jbottomley@parallels.com>
-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 | }; |