diff options
author | James Smart <james.smart@emulex.com> | 2010-02-26 14:15:57 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-03-03 08:40:09 -0500 |
commit | 0c9ab6f5cb28199ef5de84874d135ed44f64d92b (patch) | |
tree | 51140c5edce1250e0c06b5a38b540b533b092247 /drivers/scsi/lpfc/lpfc_hbadisc.c | |
parent | fc2b989be9190f3311a5ae41289828e24897a20e (diff) |
[SCSI] lpfc 8.3.10: Added round robin FCF failover
- Added round robin FCF failover on initial or FCF rediscovery FLOGI failure.
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 486 |
1 files changed, 388 insertions, 98 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index f28ce40dc349..c555e3b7f202 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -1481,8 +1481,6 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba, | |||
1481 | int | 1481 | int |
1482 | lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf) | 1482 | lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf) |
1483 | { | 1483 | { |
1484 | LPFC_MBOXQ_t *mbox; | ||
1485 | int rc; | ||
1486 | /* | 1484 | /* |
1487 | * If the Link is up and no FCoE events while in the | 1485 | * If the Link is up and no FCoE events while in the |
1488 | * FCF discovery, no need to restart FCF discovery. | 1486 | * FCF discovery, no need to restart FCF discovery. |
@@ -1491,88 +1489,70 @@ lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf) | |||
1491 | (phba->fcoe_eventtag == phba->fcoe_eventtag_at_fcf_scan)) | 1489 | (phba->fcoe_eventtag == phba->fcoe_eventtag_at_fcf_scan)) |
1492 | return 0; | 1490 | return 0; |
1493 | 1491 | ||
1492 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP, | ||
1493 | "2768 Pending link or FCF event during current " | ||
1494 | "handling of the previous event: link_state:x%x, " | ||
1495 | "evt_tag_at_scan:x%x, evt_tag_current:x%x\n", | ||
1496 | phba->link_state, phba->fcoe_eventtag_at_fcf_scan, | ||
1497 | phba->fcoe_eventtag); | ||
1498 | |||
1494 | spin_lock_irq(&phba->hbalock); | 1499 | spin_lock_irq(&phba->hbalock); |
1495 | phba->fcf.fcf_flag &= ~FCF_AVAILABLE; | 1500 | phba->fcf.fcf_flag &= ~FCF_AVAILABLE; |
1496 | spin_unlock_irq(&phba->hbalock); | 1501 | spin_unlock_irq(&phba->hbalock); |
1497 | 1502 | ||
1498 | if (phba->link_state >= LPFC_LINK_UP) | 1503 | if (phba->link_state >= LPFC_LINK_UP) { |
1499 | lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); | 1504 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, |
1500 | else { | 1505 | "2780 Restart FCF table scan due to " |
1506 | "pending FCF event:evt_tag_at_scan:x%x, " | ||
1507 | "evt_tag_current:x%x\n", | ||
1508 | phba->fcoe_eventtag_at_fcf_scan, | ||
1509 | phba->fcoe_eventtag); | ||
1510 | lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST); | ||
1511 | } else { | ||
1501 | /* | 1512 | /* |
1502 | * Do not continue FCF discovery and clear FCF_DISC_INPROGRESS | 1513 | * Do not continue FCF discovery and clear FCF_DISC_INPROGRESS |
1503 | * flag | 1514 | * flag |
1504 | */ | 1515 | */ |
1505 | spin_lock_irq(&phba->hbalock); | 1516 | spin_lock_irq(&phba->hbalock); |
1506 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; | 1517 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; |
1507 | phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | | 1518 | phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | FCF_DISCOVERY); |
1508 | FCF_DEAD_FOVER | | ||
1509 | FCF_CVL_FOVER); | ||
1510 | spin_unlock_irq(&phba->hbalock); | 1519 | spin_unlock_irq(&phba->hbalock); |
1511 | } | 1520 | } |
1512 | 1521 | ||
1522 | /* Unregister the currently registered FCF if required */ | ||
1513 | if (unreg_fcf) { | 1523 | if (unreg_fcf) { |
1514 | spin_lock_irq(&phba->hbalock); | 1524 | spin_lock_irq(&phba->hbalock); |
1515 | phba->fcf.fcf_flag &= ~FCF_REGISTERED; | 1525 | phba->fcf.fcf_flag &= ~FCF_REGISTERED; |
1516 | spin_unlock_irq(&phba->hbalock); | 1526 | spin_unlock_irq(&phba->hbalock); |
1517 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 1527 | lpfc_sli4_unregister_fcf(phba); |
1518 | if (!mbox) { | ||
1519 | lpfc_printf_log(phba, KERN_ERR, | ||
1520 | LOG_DISCOVERY|LOG_MBOX, | ||
1521 | "2610 UNREG_FCFI mbox allocation failed\n"); | ||
1522 | return 1; | ||
1523 | } | ||
1524 | lpfc_unreg_fcfi(mbox, phba->fcf.fcfi); | ||
1525 | mbox->vport = phba->pport; | ||
1526 | mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl; | ||
1527 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | ||
1528 | if (rc == MBX_NOT_FINISHED) { | ||
1529 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
1530 | "2611 UNREG_FCFI issue mbox failed\n"); | ||
1531 | mempool_free(mbox, phba->mbox_mem_pool); | ||
1532 | } | ||
1533 | } | 1528 | } |
1534 | |||
1535 | return 1; | 1529 | return 1; |
1536 | } | 1530 | } |
1537 | 1531 | ||
1538 | /** | 1532 | /** |
1539 | * lpfc_mbx_cmpl_read_fcf_record - Completion handler for read_fcf mbox. | 1533 | * lpfc_sli4_fcf_rec_mbox_parse - parse non-embedded fcf record mailbox command |
1540 | * @phba: pointer to lpfc hba data structure. | 1534 | * @phba: pointer to lpfc hba data structure. |
1541 | * @mboxq: pointer to mailbox object. | 1535 | * @mboxq: pointer to mailbox object. |
1536 | * @next_fcf_index: pointer to holder of next fcf index. | ||
1542 | * | 1537 | * |
1543 | * This function iterate through all the fcf records available in | 1538 | * This routine parses the non-embedded fcf mailbox command by performing the |
1544 | * HBA and choose the optimal FCF record for discovery. After finding | 1539 | * necessarily error checking, non-embedded read FCF record mailbox command |
1545 | * the FCF for discovery it register the FCF record and kick start | 1540 | * SGE parsing, and endianness swapping. |
1546 | * discovery. | 1541 | * |
1547 | * If FCF_IN_USE flag is set in currently used FCF, the routine try to | 1542 | * Returns the pointer to the new FCF record in the non-embedded mailbox |
1548 | * use a FCF record which match fabric name and mac address of the | 1543 | * command DMA memory if successfully, other NULL. |
1549 | * currently used FCF record. | ||
1550 | * If the driver support only one FCF, it will try to use the FCF record | ||
1551 | * used by BOOT_BIOS. | ||
1552 | */ | 1544 | */ |
1553 | void | 1545 | static struct fcf_record * |
1554 | lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | 1546 | lpfc_sli4_fcf_rec_mbox_parse(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, |
1547 | uint16_t *next_fcf_index) | ||
1555 | { | 1548 | { |
1556 | void *virt_addr; | 1549 | void *virt_addr; |
1557 | dma_addr_t phys_addr; | 1550 | dma_addr_t phys_addr; |
1558 | uint8_t *bytep; | ||
1559 | struct lpfc_mbx_sge sge; | 1551 | struct lpfc_mbx_sge sge; |
1560 | struct lpfc_mbx_read_fcf_tbl *read_fcf; | 1552 | struct lpfc_mbx_read_fcf_tbl *read_fcf; |
1561 | uint32_t shdr_status, shdr_add_status; | 1553 | uint32_t shdr_status, shdr_add_status; |
1562 | union lpfc_sli4_cfg_shdr *shdr; | 1554 | union lpfc_sli4_cfg_shdr *shdr; |
1563 | struct fcf_record *new_fcf_record; | 1555 | struct fcf_record *new_fcf_record; |
1564 | uint32_t boot_flag, addr_mode; | ||
1565 | uint32_t next_fcf_index; | ||
1566 | struct lpfc_fcf_rec *fcf_rec = NULL; | ||
1567 | unsigned long iflags; | ||
1568 | uint16_t vlan_id; | ||
1569 | int rc; | ||
1570 | |||
1571 | /* If there is pending FCoE event restart FCF table scan */ | ||
1572 | if (lpfc_check_pending_fcoe_event(phba, 0)) { | ||
1573 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
1574 | return; | ||
1575 | } | ||
1576 | 1556 | ||
1577 | /* Get the first SGE entry from the non-embedded DMA memory. This | 1557 | /* Get the first SGE entry from the non-embedded DMA memory. This |
1578 | * routine only uses a single SGE. | 1558 | * routine only uses a single SGE. |
@@ -1583,59 +1563,183 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1583 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | 1563 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, |
1584 | "2524 Failed to get the non-embedded SGE " | 1564 | "2524 Failed to get the non-embedded SGE " |
1585 | "virtual address\n"); | 1565 | "virtual address\n"); |
1586 | goto out; | 1566 | return NULL; |
1587 | } | 1567 | } |
1588 | virt_addr = mboxq->sge_array->addr[0]; | 1568 | virt_addr = mboxq->sge_array->addr[0]; |
1589 | 1569 | ||
1590 | shdr = (union lpfc_sli4_cfg_shdr *)virt_addr; | 1570 | shdr = (union lpfc_sli4_cfg_shdr *)virt_addr; |
1591 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | 1571 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); |
1592 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, | 1572 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); |
1593 | &shdr->response); | ||
1594 | /* | ||
1595 | * The FCF Record was read and there is no reason for the driver | ||
1596 | * to maintain the FCF record data or memory. Instead, just need | ||
1597 | * to book keeping the FCFIs can be used. | ||
1598 | */ | ||
1599 | if (shdr_status || shdr_add_status) { | 1573 | if (shdr_status || shdr_add_status) { |
1600 | if (shdr_status == STATUS_FCF_TABLE_EMPTY) { | 1574 | if (shdr_status == STATUS_FCF_TABLE_EMPTY) |
1601 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 1575 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP, |
1602 | "2726 READ_FCF_RECORD Indicates empty " | 1576 | "2726 READ_FCF_RECORD Indicates empty " |
1603 | "FCF table.\n"); | 1577 | "FCF table.\n"); |
1604 | } else { | 1578 | else |
1605 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 1579 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP, |
1606 | "2521 READ_FCF_RECORD mailbox failed " | 1580 | "2521 READ_FCF_RECORD mailbox failed " |
1607 | "with status x%x add_status x%x, mbx\n", | 1581 | "with status x%x add_status x%x, " |
1608 | shdr_status, shdr_add_status); | 1582 | "mbx\n", shdr_status, shdr_add_status); |
1609 | } | 1583 | return NULL; |
1610 | goto out; | ||
1611 | } | 1584 | } |
1612 | /* Interpreting the returned information of FCF records */ | 1585 | |
1586 | /* Interpreting the returned information of the FCF record */ | ||
1613 | read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr; | 1587 | read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr; |
1614 | lpfc_sli_pcimem_bcopy(read_fcf, read_fcf, | 1588 | lpfc_sli_pcimem_bcopy(read_fcf, read_fcf, |
1615 | sizeof(struct lpfc_mbx_read_fcf_tbl)); | 1589 | sizeof(struct lpfc_mbx_read_fcf_tbl)); |
1616 | next_fcf_index = bf_get(lpfc_mbx_read_fcf_tbl_nxt_vindx, read_fcf); | 1590 | *next_fcf_index = bf_get(lpfc_mbx_read_fcf_tbl_nxt_vindx, read_fcf); |
1617 | |||
1618 | new_fcf_record = (struct fcf_record *)(virt_addr + | 1591 | new_fcf_record = (struct fcf_record *)(virt_addr + |
1619 | sizeof(struct lpfc_mbx_read_fcf_tbl)); | 1592 | sizeof(struct lpfc_mbx_read_fcf_tbl)); |
1620 | lpfc_sli_pcimem_bcopy(new_fcf_record, new_fcf_record, | 1593 | lpfc_sli_pcimem_bcopy(new_fcf_record, new_fcf_record, |
1621 | sizeof(struct fcf_record)); | 1594 | sizeof(struct fcf_record)); |
1622 | bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr); | ||
1623 | 1595 | ||
1596 | return new_fcf_record; | ||
1597 | } | ||
1598 | |||
1599 | /** | ||
1600 | * lpfc_sli4_log_fcf_record_info - Log the information of a fcf record | ||
1601 | * @phba: pointer to lpfc hba data structure. | ||
1602 | * @fcf_record: pointer to the fcf record. | ||
1603 | * @vlan_id: the lowest vlan identifier associated to this fcf record. | ||
1604 | * @next_fcf_index: the index to the next fcf record in hba's fcf table. | ||
1605 | * | ||
1606 | * This routine logs the detailed FCF record if the LOG_FIP loggin is | ||
1607 | * enabled. | ||
1608 | **/ | ||
1609 | static void | ||
1610 | lpfc_sli4_log_fcf_record_info(struct lpfc_hba *phba, | ||
1611 | struct fcf_record *fcf_record, | ||
1612 | uint16_t vlan_id, | ||
1613 | uint16_t next_fcf_index) | ||
1614 | { | ||
1615 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP, | ||
1616 | "2764 READ_FCF_RECORD:\n" | ||
1617 | "\tFCF_Index : x%x\n" | ||
1618 | "\tFCF_Avail : x%x\n" | ||
1619 | "\tFCF_Valid : x%x\n" | ||
1620 | "\tFIP_Priority : x%x\n" | ||
1621 | "\tMAC_Provider : x%x\n" | ||
1622 | "\tLowest VLANID : x%x\n" | ||
1623 | "\tFCF_MAC Addr : x%x:%x:%x:%x:%x:%x\n" | ||
1624 | "\tFabric_Name : x%x:%x:%x:%x:%x:%x:%x:%x\n" | ||
1625 | "\tSwitch_Name : x%x:%x:%x:%x:%x:%x:%x:%x\n" | ||
1626 | "\tNext_FCF_Index: x%x\n", | ||
1627 | bf_get(lpfc_fcf_record_fcf_index, fcf_record), | ||
1628 | bf_get(lpfc_fcf_record_fcf_avail, fcf_record), | ||
1629 | bf_get(lpfc_fcf_record_fcf_valid, fcf_record), | ||
1630 | fcf_record->fip_priority, | ||
1631 | bf_get(lpfc_fcf_record_mac_addr_prov, fcf_record), | ||
1632 | vlan_id, | ||
1633 | bf_get(lpfc_fcf_record_mac_0, fcf_record), | ||
1634 | bf_get(lpfc_fcf_record_mac_1, fcf_record), | ||
1635 | bf_get(lpfc_fcf_record_mac_2, fcf_record), | ||
1636 | bf_get(lpfc_fcf_record_mac_3, fcf_record), | ||
1637 | bf_get(lpfc_fcf_record_mac_4, fcf_record), | ||
1638 | bf_get(lpfc_fcf_record_mac_5, fcf_record), | ||
1639 | bf_get(lpfc_fcf_record_fab_name_0, fcf_record), | ||
1640 | bf_get(lpfc_fcf_record_fab_name_1, fcf_record), | ||
1641 | bf_get(lpfc_fcf_record_fab_name_2, fcf_record), | ||
1642 | bf_get(lpfc_fcf_record_fab_name_3, fcf_record), | ||
1643 | bf_get(lpfc_fcf_record_fab_name_4, fcf_record), | ||
1644 | bf_get(lpfc_fcf_record_fab_name_5, fcf_record), | ||
1645 | bf_get(lpfc_fcf_record_fab_name_6, fcf_record), | ||
1646 | bf_get(lpfc_fcf_record_fab_name_7, fcf_record), | ||
1647 | bf_get(lpfc_fcf_record_switch_name_0, fcf_record), | ||
1648 | bf_get(lpfc_fcf_record_switch_name_1, fcf_record), | ||
1649 | bf_get(lpfc_fcf_record_switch_name_2, fcf_record), | ||
1650 | bf_get(lpfc_fcf_record_switch_name_3, fcf_record), | ||
1651 | bf_get(lpfc_fcf_record_switch_name_4, fcf_record), | ||
1652 | bf_get(lpfc_fcf_record_switch_name_5, fcf_record), | ||
1653 | bf_get(lpfc_fcf_record_switch_name_6, fcf_record), | ||
1654 | bf_get(lpfc_fcf_record_switch_name_7, fcf_record), | ||
1655 | next_fcf_index); | ||
1656 | } | ||
1657 | |||
1658 | /** | ||
1659 | * lpfc_mbx_cmpl_fcf_scan_read_fcf_rec - fcf scan read_fcf mbox cmpl handler. | ||
1660 | * @phba: pointer to lpfc hba data structure. | ||
1661 | * @mboxq: pointer to mailbox object. | ||
1662 | * | ||
1663 | * This function iterates through all the fcf records available in | ||
1664 | * HBA and chooses the optimal FCF record for discovery. After finding | ||
1665 | * the FCF for discovery it registers the FCF record and kicks start | ||
1666 | * discovery. | ||
1667 | * If FCF_IN_USE flag is set in currently used FCF, the routine tries to | ||
1668 | * use an FCF record which matches fabric name and mac address of the | ||
1669 | * currently used FCF record. | ||
1670 | * If the driver supports only one FCF, it will try to use the FCF record | ||
1671 | * used by BOOT_BIOS. | ||
1672 | */ | ||
1673 | void | ||
1674 | lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
1675 | { | ||
1676 | struct fcf_record *new_fcf_record; | ||
1677 | uint32_t boot_flag, addr_mode; | ||
1678 | uint16_t fcf_index, next_fcf_index; | ||
1679 | struct lpfc_fcf_rec *fcf_rec = NULL; | ||
1680 | uint16_t vlan_id; | ||
1681 | int rc; | ||
1682 | |||
1683 | /* If there is pending FCoE event restart FCF table scan */ | ||
1684 | if (lpfc_check_pending_fcoe_event(phba, 0)) { | ||
1685 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
1686 | return; | ||
1687 | } | ||
1688 | |||
1689 | /* Parse the FCF record from the non-embedded mailbox command */ | ||
1690 | new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq, | ||
1691 | &next_fcf_index); | ||
1692 | if (!new_fcf_record) { | ||
1693 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, | ||
1694 | "2765 Mailbox command READ_FCF_RECORD " | ||
1695 | "failed to retrieve a FCF record.\n"); | ||
1696 | /* Let next new FCF event trigger fast failover */ | ||
1697 | spin_lock_irq(&phba->hbalock); | ||
1698 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; | ||
1699 | spin_unlock_irq(&phba->hbalock); | ||
1700 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
1701 | return; | ||
1702 | } | ||
1703 | |||
1704 | /* Check the FCF record against the connection list */ | ||
1624 | rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag, | 1705 | rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag, |
1625 | &addr_mode, &vlan_id); | 1706 | &addr_mode, &vlan_id); |
1707 | |||
1708 | /* Log the FCF record information if turned on */ | ||
1709 | lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id, | ||
1710 | next_fcf_index); | ||
1711 | |||
1626 | /* | 1712 | /* |
1627 | * If the fcf record does not match with connect list entries | 1713 | * If the fcf record does not match with connect list entries |
1628 | * read the next entry. | 1714 | * read the next entry; otherwise, this is an eligible FCF |
1715 | * record for round robin FCF failover. | ||
1629 | */ | 1716 | */ |
1630 | if (!rc) | 1717 | if (!rc) { |
1718 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, | ||
1719 | "2781 FCF record fcf_index:x%x failed FCF " | ||
1720 | "connection list check, fcf_avail:x%x, " | ||
1721 | "fcf_valid:x%x\n", | ||
1722 | bf_get(lpfc_fcf_record_fcf_index, | ||
1723 | new_fcf_record), | ||
1724 | bf_get(lpfc_fcf_record_fcf_avail, | ||
1725 | new_fcf_record), | ||
1726 | bf_get(lpfc_fcf_record_fcf_valid, | ||
1727 | new_fcf_record)); | ||
1631 | goto read_next_fcf; | 1728 | goto read_next_fcf; |
1729 | } else { | ||
1730 | fcf_index = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record); | ||
1731 | rc = lpfc_sli4_fcf_rr_index_set(phba, fcf_index); | ||
1732 | if (rc) | ||
1733 | goto read_next_fcf; | ||
1734 | } | ||
1735 | |||
1632 | /* | 1736 | /* |
1633 | * If this is not the first FCF discovery of the HBA, use last | 1737 | * If this is not the first FCF discovery of the HBA, use last |
1634 | * FCF record for the discovery. The condition that a rescan | 1738 | * FCF record for the discovery. The condition that a rescan |
1635 | * matches the in-use FCF record: fabric name, switch name, mac | 1739 | * matches the in-use FCF record: fabric name, switch name, mac |
1636 | * address, and vlan_id. | 1740 | * address, and vlan_id. |
1637 | */ | 1741 | */ |
1638 | spin_lock_irqsave(&phba->hbalock, iflags); | 1742 | spin_lock_irq(&phba->hbalock); |
1639 | if (phba->fcf.fcf_flag & FCF_IN_USE) { | 1743 | if (phba->fcf.fcf_flag & FCF_IN_USE) { |
1640 | if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name, | 1744 | if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name, |
1641 | new_fcf_record) && | 1745 | new_fcf_record) && |
@@ -1652,9 +1756,8 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1652 | else if (phba->fcf.fcf_flag & FCF_REDISC_FOV) | 1756 | else if (phba->fcf.fcf_flag & FCF_REDISC_FOV) |
1653 | /* If in fast failover, mark it's completed */ | 1757 | /* If in fast failover, mark it's completed */ |
1654 | phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | | 1758 | phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | |
1655 | FCF_DEAD_FOVER | | 1759 | FCF_DISCOVERY); |
1656 | FCF_CVL_FOVER); | 1760 | spin_unlock_irq(&phba->hbalock); |
1657 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
1658 | goto out; | 1761 | goto out; |
1659 | } | 1762 | } |
1660 | /* | 1763 | /* |
@@ -1665,7 +1768,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1665 | * next candidate. | 1768 | * next candidate. |
1666 | */ | 1769 | */ |
1667 | if (!(phba->fcf.fcf_flag & FCF_REDISC_FOV)) { | 1770 | if (!(phba->fcf.fcf_flag & FCF_REDISC_FOV)) { |
1668 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 1771 | spin_unlock_irq(&phba->hbalock); |
1669 | goto read_next_fcf; | 1772 | goto read_next_fcf; |
1670 | } | 1773 | } |
1671 | } | 1774 | } |
@@ -1688,7 +1791,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1688 | /* Choose this FCF record */ | 1791 | /* Choose this FCF record */ |
1689 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, | 1792 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, |
1690 | addr_mode, vlan_id, BOOT_ENABLE); | 1793 | addr_mode, vlan_id, BOOT_ENABLE); |
1691 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 1794 | spin_unlock_irq(&phba->hbalock); |
1692 | goto read_next_fcf; | 1795 | goto read_next_fcf; |
1693 | } | 1796 | } |
1694 | /* | 1797 | /* |
@@ -1697,7 +1800,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1697 | * the next FCF record. | 1800 | * the next FCF record. |
1698 | */ | 1801 | */ |
1699 | if (!boot_flag && (fcf_rec->flag & BOOT_ENABLE)) { | 1802 | if (!boot_flag && (fcf_rec->flag & BOOT_ENABLE)) { |
1700 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 1803 | spin_unlock_irq(&phba->hbalock); |
1701 | goto read_next_fcf; | 1804 | goto read_next_fcf; |
1702 | } | 1805 | } |
1703 | /* | 1806 | /* |
@@ -1709,7 +1812,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1709 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, | 1812 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, |
1710 | addr_mode, vlan_id, 0); | 1813 | addr_mode, vlan_id, 0); |
1711 | } | 1814 | } |
1712 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 1815 | spin_unlock_irq(&phba->hbalock); |
1713 | goto read_next_fcf; | 1816 | goto read_next_fcf; |
1714 | } | 1817 | } |
1715 | /* | 1818 | /* |
@@ -1722,7 +1825,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1722 | BOOT_ENABLE : 0)); | 1825 | BOOT_ENABLE : 0)); |
1723 | phba->fcf.fcf_flag |= FCF_AVAILABLE; | 1826 | phba->fcf.fcf_flag |= FCF_AVAILABLE; |
1724 | } | 1827 | } |
1725 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 1828 | spin_unlock_irq(&phba->hbalock); |
1726 | goto read_next_fcf; | 1829 | goto read_next_fcf; |
1727 | 1830 | ||
1728 | read_next_fcf: | 1831 | read_next_fcf: |
@@ -1738,9 +1841,22 @@ read_next_fcf: | |||
1738 | * FCF scan inprogress, and do nothing | 1841 | * FCF scan inprogress, and do nothing |
1739 | */ | 1842 | */ |
1740 | if (!(phba->fcf.failover_rec.flag & RECORD_VALID)) { | 1843 | if (!(phba->fcf.failover_rec.flag & RECORD_VALID)) { |
1741 | spin_lock_irqsave(&phba->hbalock, iflags); | 1844 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, |
1845 | "2782 No suitable FCF record " | ||
1846 | "found during this round of " | ||
1847 | "post FCF rediscovery scan: " | ||
1848 | "fcf_evt_tag:x%x, fcf_index: " | ||
1849 | "x%x\n", | ||
1850 | phba->fcoe_eventtag_at_fcf_scan, | ||
1851 | bf_get(lpfc_fcf_record_fcf_index, | ||
1852 | new_fcf_record)); | ||
1853 | /* | ||
1854 | * Let next new FCF event trigger fast | ||
1855 | * failover | ||
1856 | */ | ||
1857 | spin_lock_irq(&phba->hbalock); | ||
1742 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; | 1858 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; |
1743 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 1859 | spin_unlock_irq(&phba->hbalock); |
1744 | return; | 1860 | return; |
1745 | } | 1861 | } |
1746 | /* | 1862 | /* |
@@ -1752,18 +1868,23 @@ read_next_fcf: | |||
1752 | * record. | 1868 | * record. |
1753 | */ | 1869 | */ |
1754 | 1870 | ||
1755 | /* unregister the current in-use FCF record */ | 1871 | /* Unregister the current in-use FCF record */ |
1756 | lpfc_unregister_fcf(phba); | 1872 | lpfc_unregister_fcf(phba); |
1757 | /* replace in-use record with the new record */ | 1873 | |
1874 | /* Replace in-use record with the new record */ | ||
1758 | memcpy(&phba->fcf.current_rec, | 1875 | memcpy(&phba->fcf.current_rec, |
1759 | &phba->fcf.failover_rec, | 1876 | &phba->fcf.failover_rec, |
1760 | sizeof(struct lpfc_fcf_rec)); | 1877 | sizeof(struct lpfc_fcf_rec)); |
1761 | /* mark the FCF fast failover completed */ | 1878 | /* mark the FCF fast failover completed */ |
1762 | spin_lock_irqsave(&phba->hbalock, iflags); | 1879 | spin_lock_irq(&phba->hbalock); |
1763 | phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | | 1880 | phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; |
1764 | FCF_DEAD_FOVER | | 1881 | spin_unlock_irq(&phba->hbalock); |
1765 | FCF_CVL_FOVER); | 1882 | /* |
1766 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 1883 | * Set up the initial registered FCF index for FLOGI |
1884 | * round robin FCF failover. | ||
1885 | */ | ||
1886 | phba->fcf.fcf_rr_init_indx = | ||
1887 | phba->fcf.failover_rec.fcf_indx; | ||
1767 | /* Register to the new FCF record */ | 1888 | /* Register to the new FCF record */ |
1768 | lpfc_register_fcf(phba); | 1889 | lpfc_register_fcf(phba); |
1769 | } else { | 1890 | } else { |
@@ -1776,13 +1897,25 @@ read_next_fcf: | |||
1776 | return; | 1897 | return; |
1777 | /* | 1898 | /* |
1778 | * Otherwise, initial scan or post linkdown rescan, | 1899 | * Otherwise, initial scan or post linkdown rescan, |
1779 | * register with the best fit FCF record found so | 1900 | * register with the best FCF record found so far |
1780 | * far through the scanning process. | 1901 | * through the FCF scanning process. |
1902 | */ | ||
1903 | |||
1904 | /* mark the initial FCF discovery completed */ | ||
1905 | spin_lock_irq(&phba->hbalock); | ||
1906 | phba->fcf.fcf_flag &= ~FCF_INIT_DISC; | ||
1907 | spin_unlock_irq(&phba->hbalock); | ||
1908 | /* | ||
1909 | * Set up the initial registered FCF index for FLOGI | ||
1910 | * round robin FCF failover | ||
1781 | */ | 1911 | */ |
1912 | phba->fcf.fcf_rr_init_indx = | ||
1913 | phba->fcf.current_rec.fcf_indx; | ||
1914 | /* Register to the new FCF record */ | ||
1782 | lpfc_register_fcf(phba); | 1915 | lpfc_register_fcf(phba); |
1783 | } | 1916 | } |
1784 | } else | 1917 | } else |
1785 | lpfc_sli4_read_fcf_record(phba, next_fcf_index); | 1918 | lpfc_sli4_fcf_scan_read_fcf_rec(phba, next_fcf_index); |
1786 | return; | 1919 | return; |
1787 | 1920 | ||
1788 | out: | 1921 | out: |
@@ -1793,6 +1926,141 @@ out: | |||
1793 | } | 1926 | } |
1794 | 1927 | ||
1795 | /** | 1928 | /** |
1929 | * lpfc_mbx_cmpl_fcf_rr_read_fcf_rec - fcf round robin read_fcf mbox cmpl hdler | ||
1930 | * @phba: pointer to lpfc hba data structure. | ||
1931 | * @mboxq: pointer to mailbox object. | ||
1932 | * | ||
1933 | * This is the callback function for FLOGI failure round robin FCF failover | ||
1934 | * read FCF record mailbox command from the eligible FCF record bmask for | ||
1935 | * performing the failover. If the FCF read back is not valid/available, it | ||
1936 | * fails through to retrying FLOGI to the currently registered FCF again. | ||
1937 | * Otherwise, if the FCF read back is valid and available, it will set the | ||
1938 | * newly read FCF record to the failover FCF record, unregister currently | ||
1939 | * registered FCF record, copy the failover FCF record to the current | ||
1940 | * FCF record, and then register the current FCF record before proceeding | ||
1941 | * to trying FLOGI on the new failover FCF. | ||
1942 | */ | ||
1943 | void | ||
1944 | lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
1945 | { | ||
1946 | struct fcf_record *new_fcf_record; | ||
1947 | uint32_t boot_flag, addr_mode; | ||
1948 | uint16_t next_fcf_index; | ||
1949 | uint16_t current_fcf_index; | ||
1950 | uint16_t vlan_id; | ||
1951 | |||
1952 | /* If link state is not up, stop the round robin failover process */ | ||
1953 | if (phba->link_state < LPFC_LINK_UP) { | ||
1954 | spin_lock_irq(&phba->hbalock); | ||
1955 | phba->fcf.fcf_flag &= ~FCF_DISCOVERY; | ||
1956 | spin_unlock_irq(&phba->hbalock); | ||
1957 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
1958 | return; | ||
1959 | } | ||
1960 | |||
1961 | /* Parse the FCF record from the non-embedded mailbox command */ | ||
1962 | new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq, | ||
1963 | &next_fcf_index); | ||
1964 | if (!new_fcf_record) { | ||
1965 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, | ||
1966 | "2766 Mailbox command READ_FCF_RECORD " | ||
1967 | "failed to retrieve a FCF record.\n"); | ||
1968 | goto out; | ||
1969 | } | ||
1970 | |||
1971 | /* Get the needed parameters from FCF record */ | ||
1972 | lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag, | ||
1973 | &addr_mode, &vlan_id); | ||
1974 | |||
1975 | /* Log the FCF record information if turned on */ | ||
1976 | lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id, | ||
1977 | next_fcf_index); | ||
1978 | |||
1979 | /* Upload new FCF record to the failover FCF record */ | ||
1980 | spin_lock_irq(&phba->hbalock); | ||
1981 | __lpfc_update_fcf_record(phba, &phba->fcf.failover_rec, | ||
1982 | new_fcf_record, addr_mode, vlan_id, | ||
1983 | (boot_flag ? BOOT_ENABLE : 0)); | ||
1984 | spin_unlock_irq(&phba->hbalock); | ||
1985 | |||
1986 | current_fcf_index = phba->fcf.current_rec.fcf_indx; | ||
1987 | |||
1988 | /* Unregister the current in-use FCF record */ | ||
1989 | lpfc_unregister_fcf(phba); | ||
1990 | |||
1991 | /* Replace in-use record with the new record */ | ||
1992 | memcpy(&phba->fcf.current_rec, &phba->fcf.failover_rec, | ||
1993 | sizeof(struct lpfc_fcf_rec)); | ||
1994 | |||
1995 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP, | ||
1996 | "2783 FLOGI round robin FCF failover from FCF " | ||
1997 | "(index:x%x) to FCF (index:x%x).\n", | ||
1998 | current_fcf_index, | ||
1999 | bf_get(lpfc_fcf_record_fcf_index, new_fcf_record)); | ||
2000 | |||
2001 | out: | ||
2002 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
2003 | lpfc_register_fcf(phba); | ||
2004 | } | ||
2005 | |||
2006 | /** | ||
2007 | * lpfc_mbx_cmpl_read_fcf_rec - read fcf completion handler. | ||
2008 | * @phba: pointer to lpfc hba data structure. | ||
2009 | * @mboxq: pointer to mailbox object. | ||
2010 | * | ||
2011 | * This is the callback function of read FCF record mailbox command for | ||
2012 | * updating the eligible FCF bmask for FLOGI failure round robin FCF | ||
2013 | * failover when a new FCF event happened. If the FCF read back is | ||
2014 | * valid/available and it passes the connection list check, it updates | ||
2015 | * the bmask for the eligible FCF record for round robin failover. | ||
2016 | */ | ||
2017 | void | ||
2018 | lpfc_mbx_cmpl_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
2019 | { | ||
2020 | struct fcf_record *new_fcf_record; | ||
2021 | uint32_t boot_flag, addr_mode; | ||
2022 | uint16_t fcf_index, next_fcf_index; | ||
2023 | uint16_t vlan_id; | ||
2024 | int rc; | ||
2025 | |||
2026 | /* If link state is not up, no need to proceed */ | ||
2027 | if (phba->link_state < LPFC_LINK_UP) | ||
2028 | goto out; | ||
2029 | |||
2030 | /* If FCF discovery period is over, no need to proceed */ | ||
2031 | if (phba->fcf.fcf_flag & FCF_DISCOVERY) | ||
2032 | goto out; | ||
2033 | |||
2034 | /* Parse the FCF record from the non-embedded mailbox command */ | ||
2035 | new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq, | ||
2036 | &next_fcf_index); | ||
2037 | if (!new_fcf_record) { | ||
2038 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP, | ||
2039 | "2767 Mailbox command READ_FCF_RECORD " | ||
2040 | "failed to retrieve a FCF record.\n"); | ||
2041 | goto out; | ||
2042 | } | ||
2043 | |||
2044 | /* Check the connection list for eligibility */ | ||
2045 | rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag, | ||
2046 | &addr_mode, &vlan_id); | ||
2047 | |||
2048 | /* Log the FCF record information if turned on */ | ||
2049 | lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id, | ||
2050 | next_fcf_index); | ||
2051 | |||
2052 | if (!rc) | ||
2053 | goto out; | ||
2054 | |||
2055 | /* Update the eligible FCF record index bmask */ | ||
2056 | fcf_index = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record); | ||
2057 | rc = lpfc_sli4_fcf_rr_index_set(phba, fcf_index); | ||
2058 | |||
2059 | out: | ||
2060 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
2061 | } | ||
2062 | |||
2063 | /** | ||
1796 | * lpfc_init_vpi_cmpl - Completion handler for init_vpi mbox command. | 2064 | * lpfc_init_vpi_cmpl - Completion handler for init_vpi mbox command. |
1797 | * @phba: pointer to lpfc hba data structure. | 2065 | * @phba: pointer to lpfc hba data structure. |
1798 | * @mboxq: pointer to mailbox data structure. | 2066 | * @mboxq: pointer to mailbox data structure. |
@@ -2190,10 +2458,20 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
2190 | spin_unlock_irq(&phba->hbalock); | 2458 | spin_unlock_irq(&phba->hbalock); |
2191 | return; | 2459 | return; |
2192 | } | 2460 | } |
2461 | /* This is the initial FCF discovery scan */ | ||
2462 | phba->fcf.fcf_flag |= FCF_INIT_DISC; | ||
2193 | spin_unlock_irq(&phba->hbalock); | 2463 | spin_unlock_irq(&phba->hbalock); |
2194 | rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); | 2464 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, |
2195 | if (rc) | 2465 | "2778 Start FCF table scan at linkup\n"); |
2466 | |||
2467 | rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, | ||
2468 | LPFC_FCOE_FCF_GET_FIRST); | ||
2469 | if (rc) { | ||
2470 | spin_lock_irq(&phba->hbalock); | ||
2471 | phba->fcf.fcf_flag &= ~FCF_INIT_DISC; | ||
2472 | spin_unlock_irq(&phba->hbalock); | ||
2196 | goto out; | 2473 | goto out; |
2474 | } | ||
2197 | } | 2475 | } |
2198 | 2476 | ||
2199 | return; | 2477 | return; |
@@ -3383,8 +3661,12 @@ lpfc_unreg_hba_rpis(struct lpfc_hba *phba) | |||
3383 | shost = lpfc_shost_from_vport(vports[i]); | 3661 | shost = lpfc_shost_from_vport(vports[i]); |
3384 | spin_lock_irq(shost->host_lock); | 3662 | spin_lock_irq(shost->host_lock); |
3385 | list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) { | 3663 | list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) { |
3386 | if (ndlp->nlp_flag & NLP_RPI_VALID) | 3664 | if (ndlp->nlp_flag & NLP_RPI_VALID) { |
3665 | /* The mempool_alloc might sleep */ | ||
3666 | spin_unlock_irq(shost->host_lock); | ||
3387 | lpfc_unreg_rpi(vports[i], ndlp); | 3667 | lpfc_unreg_rpi(vports[i], ndlp); |
3668 | spin_lock_irq(shost->host_lock); | ||
3669 | } | ||
3388 | } | 3670 | } |
3389 | spin_unlock_irq(shost->host_lock); | 3671 | spin_unlock_irq(shost->host_lock); |
3390 | } | 3672 | } |
@@ -4770,13 +5052,21 @@ lpfc_unregister_fcf_rescan(struct lpfc_hba *phba) | |||
4770 | (phba->link_state < LPFC_LINK_UP)) | 5052 | (phba->link_state < LPFC_LINK_UP)) |
4771 | return; | 5053 | return; |
4772 | 5054 | ||
4773 | rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); | 5055 | /* This is considered as the initial FCF discovery scan */ |
5056 | spin_lock_irq(&phba->hbalock); | ||
5057 | phba->fcf.fcf_flag |= FCF_INIT_DISC; | ||
5058 | spin_unlock_irq(&phba->hbalock); | ||
5059 | rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST); | ||
4774 | 5060 | ||
4775 | if (rc) | 5061 | if (rc) { |
5062 | spin_lock_irq(&phba->hbalock); | ||
5063 | phba->fcf.fcf_flag &= ~FCF_INIT_DISC; | ||
5064 | spin_unlock_irq(&phba->hbalock); | ||
4776 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | 5065 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, |
4777 | "2553 lpfc_unregister_unused_fcf failed " | 5066 | "2553 lpfc_unregister_unused_fcf failed " |
4778 | "to read FCF record HBA state x%x\n", | 5067 | "to read FCF record HBA state x%x\n", |
4779 | phba->pport->port_state); | 5068 | phba->pport->port_state); |
5069 | } | ||
4780 | } | 5070 | } |
4781 | 5071 | ||
4782 | /** | 5072 | /** |