diff options
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 6 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 39 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 8 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_gs.c | 187 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 81 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 4 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 86 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 2 |
8 files changed, 401 insertions, 12 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 87f90c4f08e9..144b0f8459ce 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
| @@ -691,13 +691,13 @@ qla2x00_get_host_speed(struct Scsi_Host *shost) | |||
| 691 | uint32_t speed = 0; | 691 | uint32_t speed = 0; |
| 692 | 692 | ||
| 693 | switch (ha->link_data_rate) { | 693 | switch (ha->link_data_rate) { |
| 694 | case LDR_1GB: | 694 | case PORT_SPEED_1GB: |
| 695 | speed = 1; | 695 | speed = 1; |
| 696 | break; | 696 | break; |
| 697 | case LDR_2GB: | 697 | case PORT_SPEED_2GB: |
| 698 | speed = 2; | 698 | speed = 2; |
| 699 | break; | 699 | break; |
| 700 | case LDR_4GB: | 700 | case PORT_SPEED_4GB: |
| 701 | speed = 4; | 701 | speed = 4; |
| 702 | break; | 702 | break; |
| 703 | } | 703 | } |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 0930260aec2c..6d677b0fb551 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
| @@ -608,6 +608,7 @@ typedef struct { | |||
| 608 | */ | 608 | */ |
| 609 | #define MBC_SERDES_PARAMS 0x10 /* Serdes Tx Parameters. */ | 609 | #define MBC_SERDES_PARAMS 0x10 /* Serdes Tx Parameters. */ |
| 610 | #define MBC_GET_IOCB_STATUS 0x12 /* Get IOCB status command. */ | 610 | #define MBC_GET_IOCB_STATUS 0x12 /* Get IOCB status command. */ |
| 611 | #define MBC_PORT_PARAMS 0x1A /* Port iDMA Parameters. */ | ||
| 611 | #define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */ | 612 | #define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */ |
| 612 | #define MBC_TRACE_CONTROL 0x27 /* Trace control command. */ | 613 | #define MBC_TRACE_CONTROL 0x27 /* Trace control command. */ |
| 613 | #define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */ | 614 | #define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */ |
| @@ -1497,6 +1498,9 @@ typedef struct { | |||
| 1497 | port_id_t d_id; | 1498 | port_id_t d_id; |
| 1498 | uint8_t node_name[WWN_SIZE]; | 1499 | uint8_t node_name[WWN_SIZE]; |
| 1499 | uint8_t port_name[WWN_SIZE]; | 1500 | uint8_t port_name[WWN_SIZE]; |
| 1501 | uint8_t fabric_port_name[WWN_SIZE]; | ||
| 1502 | uint16_t fp_speeds; | ||
| 1503 | uint16_t fp_speed; | ||
| 1500 | } sw_info_t; | 1504 | } sw_info_t; |
| 1501 | 1505 | ||
| 1502 | /* | 1506 | /* |
| @@ -1524,6 +1528,9 @@ typedef struct fc_port { | |||
| 1524 | uint16_t loop_id; | 1528 | uint16_t loop_id; |
| 1525 | uint16_t old_loop_id; | 1529 | uint16_t old_loop_id; |
| 1526 | 1530 | ||
| 1531 | uint8_t fabric_port_name[WWN_SIZE]; | ||
| 1532 | uint16_t fp_speed; | ||
| 1533 | |||
| 1527 | fc_port_type_t port_type; | 1534 | fc_port_type_t port_type; |
| 1528 | 1535 | ||
| 1529 | atomic_t state; | 1536 | atomic_t state; |
| @@ -1635,6 +1642,15 @@ typedef struct fc_port { | |||
| 1635 | #define RSNN_NN_REQ_SIZE (16 + 8 + 1 + 255) | 1642 | #define RSNN_NN_REQ_SIZE (16 + 8 + 1 + 255) |
| 1636 | #define RSNN_NN_RSP_SIZE 16 | 1643 | #define RSNN_NN_RSP_SIZE 16 |
| 1637 | 1644 | ||
| 1645 | #define GFPN_ID_CMD 0x11C | ||
| 1646 | #define GFPN_ID_REQ_SIZE (16 + 4) | ||
| 1647 | #define GFPN_ID_RSP_SIZE (16 + 8) | ||
| 1648 | |||
| 1649 | #define GPSC_CMD 0x127 | ||
| 1650 | #define GPSC_REQ_SIZE (16 + 8) | ||
| 1651 | #define GPSC_RSP_SIZE (16 + 2 + 2) | ||
| 1652 | |||
| 1653 | |||
| 1638 | /* | 1654 | /* |
| 1639 | * HBA attribute types. | 1655 | * HBA attribute types. |
| 1640 | */ | 1656 | */ |
| @@ -1748,7 +1764,7 @@ struct ct_sns_req { | |||
| 1748 | uint8_t reserved[3]; | 1764 | uint8_t reserved[3]; |
| 1749 | 1765 | ||
| 1750 | union { | 1766 | union { |
| 1751 | /* GA_NXT, GPN_ID, GNN_ID, GFT_ID */ | 1767 | /* GA_NXT, GPN_ID, GNN_ID, GFT_ID, GFPN_ID */ |
| 1752 | struct { | 1768 | struct { |
| 1753 | uint8_t reserved; | 1769 | uint8_t reserved; |
| 1754 | uint8_t port_id[3]; | 1770 | uint8_t port_id[3]; |
| @@ -1823,6 +1839,10 @@ struct ct_sns_req { | |||
| 1823 | struct { | 1839 | struct { |
| 1824 | uint8_t port_name[8]; | 1840 | uint8_t port_name[8]; |
| 1825 | } dpa; | 1841 | } dpa; |
| 1842 | |||
| 1843 | struct { | ||
| 1844 | uint8_t port_name[8]; | ||
| 1845 | } gpsc; | ||
| 1826 | } req; | 1846 | } req; |
| 1827 | }; | 1847 | }; |
| 1828 | 1848 | ||
| @@ -1886,6 +1906,15 @@ struct ct_sns_rsp { | |||
| 1886 | uint8_t port_name[8]; | 1906 | uint8_t port_name[8]; |
| 1887 | struct ct_fdmi_hba_attributes attrs; | 1907 | struct ct_fdmi_hba_attributes attrs; |
| 1888 | } ghat; | 1908 | } ghat; |
| 1909 | |||
| 1910 | struct { | ||
| 1911 | uint8_t port_name[8]; | ||
| 1912 | } gfpn_id; | ||
| 1913 | |||
| 1914 | struct { | ||
| 1915 | uint16_t speeds; | ||
| 1916 | uint16_t speed; | ||
| 1917 | } gpsc; | ||
| 1889 | } rsp; | 1918 | } rsp; |
| 1890 | }; | 1919 | }; |
| 1891 | 1920 | ||
| @@ -2182,11 +2211,11 @@ typedef struct scsi_qla_host { | |||
| 2182 | uint16_t max_public_loop_ids; | 2211 | uint16_t max_public_loop_ids; |
| 2183 | uint16_t min_external_loopid; /* First external loop Id */ | 2212 | uint16_t min_external_loopid; /* First external loop Id */ |
| 2184 | 2213 | ||
| 2214 | #define PORT_SPEED_UNKNOWN 0xFFFF | ||
| 2215 | #define PORT_SPEED_1GB 0x00 | ||
| 2216 | #define PORT_SPEED_2GB 0x01 | ||
| 2217 | #define PORT_SPEED_4GB 0x03 | ||
| 2185 | uint16_t link_data_rate; /* F/W operating speed */ | 2218 | uint16_t link_data_rate; /* F/W operating speed */ |
| 2186 | #define LDR_1GB 0 | ||
| 2187 | #define LDR_2GB 1 | ||
| 2188 | #define LDR_4GB 3 | ||
| 2189 | #define LDR_UNKNOWN 0xFFFF | ||
| 2190 | 2219 | ||
| 2191 | uint8_t current_topology; | 2220 | uint8_t current_topology; |
| 2192 | uint8_t prev_topology; | 2221 | uint8_t prev_topology; |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 8311ac2b93a8..c48e1d8bb100 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
| @@ -208,6 +208,12 @@ qla2x00_trace_control(scsi_qla_host_t *, uint16_t, dma_addr_t, uint16_t); | |||
| 208 | extern int | 208 | extern int |
| 209 | qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t); | 209 | qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t); |
| 210 | 210 | ||
| 211 | extern int | ||
| 212 | qla2x00_get_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t *, uint16_t *); | ||
| 213 | |||
| 214 | extern int | ||
| 215 | qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *); | ||
| 216 | |||
| 211 | /* | 217 | /* |
| 212 | * Global Function Prototypes in qla_isr.c source file. | 218 | * Global Function Prototypes in qla_isr.c source file. |
| 213 | */ | 219 | */ |
| @@ -279,6 +285,8 @@ extern int qla2x00_rsnn_nn(scsi_qla_host_t *); | |||
| 279 | extern void *qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t); | 285 | extern void *qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t); |
| 280 | extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t); | 286 | extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t); |
| 281 | extern int qla2x00_fdmi_register(scsi_qla_host_t *); | 287 | extern int qla2x00_fdmi_register(scsi_qla_host_t *); |
| 288 | extern int qla2x00_gfpn_id(scsi_qla_host_t *, sw_info_t *); | ||
| 289 | extern int qla2x00_gpsc(scsi_qla_host_t *, sw_info_t *); | ||
| 282 | 290 | ||
| 283 | /* | 291 | /* |
| 284 | * Global Function Prototypes in qla_attr.c source file. | 292 | * Global Function Prototypes in qla_attr.c source file. |
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 2ebf259fccb2..029953c1a9c8 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c | |||
| @@ -687,7 +687,6 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha) | |||
| 687 | return (rval); | 687 | return (rval); |
| 688 | } | 688 | } |
| 689 | 689 | ||
| 690 | |||
| 691 | /** | 690 | /** |
| 692 | * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query. | 691 | * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query. |
| 693 | * @ha: HA context | 692 | * @ha: HA context |
| @@ -1647,3 +1646,189 @@ qla2x00_fdmi_register(scsi_qla_host_t *ha) | |||
| 1647 | 1646 | ||
| 1648 | return rval; | 1647 | return rval; |
| 1649 | } | 1648 | } |
| 1649 | |||
| 1650 | /** | ||
| 1651 | * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query. | ||
| 1652 | * @ha: HA context | ||
| 1653 | * @list: switch info entries to populate | ||
| 1654 | * | ||
| 1655 | * Returns 0 on success. | ||
| 1656 | */ | ||
| 1657 | int | ||
| 1658 | qla2x00_gfpn_id(scsi_qla_host_t *ha, sw_info_t *list) | ||
| 1659 | { | ||
| 1660 | int rval; | ||
| 1661 | uint16_t i; | ||
| 1662 | |||
| 1663 | ms_iocb_entry_t *ms_pkt; | ||
| 1664 | struct ct_sns_req *ct_req; | ||
| 1665 | struct ct_sns_rsp *ct_rsp; | ||
| 1666 | |||
| 1667 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
| 1668 | return QLA_FUNCTION_FAILED; | ||
| 1669 | |||
| 1670 | for (i = 0; i < MAX_FIBRE_DEVICES; i++) { | ||
| 1671 | /* Issue GFPN_ID */ | ||
| 1672 | memset(list[i].fabric_port_name, 0, WWN_SIZE); | ||
| 1673 | |||
| 1674 | /* Prepare common MS IOCB */ | ||
| 1675 | ms_pkt = qla2x00_prep_ms_iocb(ha, GFPN_ID_REQ_SIZE, | ||
| 1676 | GFPN_ID_RSP_SIZE); | ||
| 1677 | |||
| 1678 | /* Prepare CT request */ | ||
| 1679 | ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFPN_ID_CMD, | ||
| 1680 | GFPN_ID_RSP_SIZE); | ||
| 1681 | ct_rsp = &ha->ct_sns->p.rsp; | ||
| 1682 | |||
| 1683 | /* Prepare CT arguments -- port_id */ | ||
| 1684 | ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; | ||
| 1685 | ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; | ||
| 1686 | ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; | ||
| 1687 | |||
| 1688 | /* Execute MS IOCB */ | ||
| 1689 | rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, | ||
| 1690 | sizeof(ms_iocb_entry_t)); | ||
| 1691 | if (rval != QLA_SUCCESS) { | ||
| 1692 | /*EMPTY*/ | ||
| 1693 | DEBUG2_3(printk("scsi(%ld): GFPN_ID issue IOCB " | ||
| 1694 | "failed (%d).\n", ha->host_no, rval)); | ||
| 1695 | } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, | ||
| 1696 | "GFPN_ID") != QLA_SUCCESS) { | ||
| 1697 | rval = QLA_FUNCTION_FAILED; | ||
| 1698 | } else { | ||
| 1699 | /* Save fabric portname */ | ||
| 1700 | memcpy(list[i].fabric_port_name, | ||
| 1701 | ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE); | ||
| 1702 | } | ||
| 1703 | |||
| 1704 | /* Last device exit. */ | ||
| 1705 | if (list[i].d_id.b.rsvd_1 != 0) | ||
| 1706 | break; | ||
| 1707 | } | ||
| 1708 | |||
| 1709 | return (rval); | ||
| 1710 | } | ||
| 1711 | |||
| 1712 | static inline void * | ||
| 1713 | qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *ha, uint32_t req_size, | ||
| 1714 | uint32_t rsp_size) | ||
| 1715 | { | ||
| 1716 | struct ct_entry_24xx *ct_pkt; | ||
| 1717 | |||
| 1718 | ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; | ||
| 1719 | memset(ct_pkt, 0, sizeof(struct ct_entry_24xx)); | ||
| 1720 | |||
| 1721 | ct_pkt->entry_type = CT_IOCB_TYPE; | ||
| 1722 | ct_pkt->entry_count = 1; | ||
| 1723 | ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id); | ||
| 1724 | ct_pkt->timeout = __constant_cpu_to_le16(59); | ||
| 1725 | ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); | ||
| 1726 | ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1); | ||
| 1727 | ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); | ||
| 1728 | ct_pkt->cmd_byte_count = cpu_to_le32(req_size); | ||
| 1729 | |||
| 1730 | ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); | ||
| 1731 | ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); | ||
| 1732 | ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; | ||
| 1733 | |||
| 1734 | ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); | ||
| 1735 | ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); | ||
| 1736 | ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; | ||
| 1737 | |||
| 1738 | return ct_pkt; | ||
| 1739 | } | ||
| 1740 | |||
| 1741 | |||
| 1742 | static inline struct ct_sns_req * | ||
| 1743 | qla24xx_prep_ct_fm_req(struct ct_sns_req *ct_req, uint16_t cmd, | ||
| 1744 | uint16_t rsp_size) | ||
| 1745 | { | ||
| 1746 | memset(ct_req, 0, sizeof(struct ct_sns_pkt)); | ||
| 1747 | |||
| 1748 | ct_req->header.revision = 0x01; | ||
| 1749 | ct_req->header.gs_type = 0xFA; | ||
| 1750 | ct_req->header.gs_subtype = 0x01; | ||
| 1751 | ct_req->command = cpu_to_be16(cmd); | ||
| 1752 | ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); | ||
| 1753 | |||
| 1754 | return ct_req; | ||
| 1755 | } | ||
| 1756 | |||
| 1757 | /** | ||
| 1758 | * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query. | ||
| 1759 | * @ha: HA context | ||
| 1760 | * @list: switch info entries to populate | ||
| 1761 | * | ||
| 1762 | * Returns 0 on success. | ||
| 1763 | */ | ||
| 1764 | int | ||
| 1765 | qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list) | ||
| 1766 | { | ||
| 1767 | int rval; | ||
| 1768 | uint16_t i; | ||
| 1769 | |||
| 1770 | ms_iocb_entry_t *ms_pkt; | ||
| 1771 | struct ct_sns_req *ct_req; | ||
| 1772 | struct ct_sns_rsp *ct_rsp; | ||
| 1773 | |||
| 1774 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
| 1775 | return QLA_FUNCTION_FAILED; | ||
| 1776 | |||
| 1777 | rval = qla2x00_mgmt_svr_login(ha); | ||
| 1778 | if (rval) | ||
| 1779 | return rval; | ||
| 1780 | |||
| 1781 | for (i = 0; i < MAX_FIBRE_DEVICES; i++) { | ||
| 1782 | /* Issue GFPN_ID */ | ||
| 1783 | list[i].fp_speeds = list[i].fp_speed = 0; | ||
| 1784 | |||
| 1785 | /* Prepare common MS IOCB */ | ||
| 1786 | ms_pkt = qla24xx_prep_ms_fm_iocb(ha, GPSC_REQ_SIZE, | ||
| 1787 | GPSC_RSP_SIZE); | ||
| 1788 | |||
| 1789 | /* Prepare CT request */ | ||
| 1790 | ct_req = qla24xx_prep_ct_fm_req(&ha->ct_sns->p.req, | ||
| 1791 | GPSC_CMD, GPSC_RSP_SIZE); | ||
| 1792 | ct_rsp = &ha->ct_sns->p.rsp; | ||
| 1793 | |||
| 1794 | /* Prepare CT arguments -- port_name */ | ||
| 1795 | memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name, | ||
| 1796 | WWN_SIZE); | ||
| 1797 | |||
| 1798 | /* Execute MS IOCB */ | ||
| 1799 | rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, | ||
| 1800 | sizeof(ms_iocb_entry_t)); | ||
| 1801 | if (rval != QLA_SUCCESS) { | ||
| 1802 | /*EMPTY*/ | ||
| 1803 | DEBUG2_3(printk("scsi(%ld): GPSC issue IOCB " | ||
| 1804 | "failed (%d).\n", ha->host_no, rval)); | ||
| 1805 | } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, | ||
| 1806 | "GPSC") != QLA_SUCCESS) { | ||
| 1807 | rval = QLA_FUNCTION_FAILED; | ||
| 1808 | } else { | ||
| 1809 | /* Save portname */ | ||
| 1810 | list[i].fp_speeds = ct_rsp->rsp.gpsc.speeds; | ||
| 1811 | list[i].fp_speed = ct_rsp->rsp.gpsc.speed; | ||
| 1812 | |||
| 1813 | DEBUG2_3(printk("scsi(%ld): GPSC ext entry - " | ||
| 1814 | "fpn %02x%02x%02x%02x%02x%02x%02x%02x speeds=%04x " | ||
| 1815 | "speed=%04x.\n", ha->host_no, | ||
| 1816 | list[i].fabric_port_name[0], | ||
| 1817 | list[i].fabric_port_name[1], | ||
| 1818 | list[i].fabric_port_name[2], | ||
| 1819 | list[i].fabric_port_name[3], | ||
| 1820 | list[i].fabric_port_name[4], | ||
| 1821 | list[i].fabric_port_name[5], | ||
| 1822 | list[i].fabric_port_name[6], | ||
| 1823 | list[i].fabric_port_name[7], | ||
| 1824 | be16_to_cpu(list[i].fp_speeds), | ||
| 1825 | be16_to_cpu(list[i].fp_speed))); | ||
| 1826 | } | ||
| 1827 | |||
| 1828 | /* Last device exit. */ | ||
| 1829 | if (list[i].d_id.b.rsvd_1 != 0) | ||
| 1830 | break; | ||
| 1831 | } | ||
| 1832 | |||
| 1833 | return (rval); | ||
| 1834 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 859649160caa..270096441f3e 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
| @@ -2074,6 +2074,19 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha) | |||
| 2074 | new_fcport->flags &= ~FCF_FABRIC_DEVICE; | 2074 | new_fcport->flags &= ~FCF_FABRIC_DEVICE; |
| 2075 | } | 2075 | } |
| 2076 | 2076 | ||
| 2077 | /* Base iIDMA settings on HBA port speed. */ | ||
| 2078 | switch (ha->link_data_rate) { | ||
| 2079 | case PORT_SPEED_1GB: | ||
| 2080 | fcport->fp_speed = cpu_to_be16(BIT_15); | ||
| 2081 | break; | ||
| 2082 | case PORT_SPEED_2GB: | ||
| 2083 | fcport->fp_speed = cpu_to_be16(BIT_14); | ||
| 2084 | break; | ||
| 2085 | case PORT_SPEED_4GB: | ||
| 2086 | fcport->fp_speed = cpu_to_be16(BIT_13); | ||
| 2087 | break; | ||
| 2088 | } | ||
| 2089 | |||
| 2077 | qla2x00_update_fcport(ha, fcport); | 2090 | qla2x00_update_fcport(ha, fcport); |
| 2078 | 2091 | ||
| 2079 | found_devs++; | 2092 | found_devs++; |
| @@ -2109,6 +2122,62 @@ qla2x00_probe_for_all_luns(scsi_qla_host_t *ha) | |||
| 2109 | } | 2122 | } |
| 2110 | } | 2123 | } |
| 2111 | 2124 | ||
| 2125 | static void | ||
| 2126 | qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) | ||
| 2127 | { | ||
| 2128 | #define LS_UNKNOWN 2 | ||
| 2129 | static char *link_speeds[5] = { "1", "2", "?", "4" }; | ||
| 2130 | int rval; | ||
| 2131 | uint16_t port_speed, mb[6]; | ||
| 2132 | |||
| 2133 | if (!IS_QLA24XX(ha)) | ||
| 2134 | return; | ||
| 2135 | |||
| 2136 | switch (be16_to_cpu(fcport->fp_speed)) { | ||
| 2137 | case BIT_15: | ||
| 2138 | port_speed = PORT_SPEED_1GB; | ||
| 2139 | break; | ||
| 2140 | case BIT_14: | ||
| 2141 | port_speed = PORT_SPEED_2GB; | ||
| 2142 | break; | ||
| 2143 | case BIT_13: | ||
| 2144 | port_speed = PORT_SPEED_4GB; | ||
| 2145 | break; | ||
| 2146 | default: | ||
| 2147 | DEBUG2(printk("scsi(%ld): %02x%02x%02x%02x%02x%02x%02x%02x -- " | ||
| 2148 | "unsupported FM port operating speed (%04x).\n", | ||
| 2149 | ha->host_no, fcport->port_name[0], fcport->port_name[1], | ||
| 2150 | fcport->port_name[2], fcport->port_name[3], | ||
| 2151 | fcport->port_name[4], fcport->port_name[5], | ||
| 2152 | fcport->port_name[6], fcport->port_name[7], | ||
| 2153 | be16_to_cpu(fcport->fp_speed))); | ||
| 2154 | port_speed = PORT_SPEED_UNKNOWN; | ||
| 2155 | break; | ||
| 2156 | } | ||
| 2157 | if (port_speed == PORT_SPEED_UNKNOWN) | ||
| 2158 | return; | ||
| 2159 | |||
| 2160 | rval = qla2x00_set_idma_speed(ha, fcport->loop_id, port_speed, mb); | ||
| 2161 | if (rval != QLA_SUCCESS) { | ||
| 2162 | DEBUG2(printk("scsi(%ld): Unable to adjust iIDMA " | ||
| 2163 | "%02x%02x%02x%02x%02x%02x%02x%02x -- %04x %x %04x %04x.\n", | ||
| 2164 | ha->host_no, fcport->port_name[0], fcport->port_name[1], | ||
| 2165 | fcport->port_name[2], fcport->port_name[3], | ||
| 2166 | fcport->port_name[4], fcport->port_name[5], | ||
| 2167 | fcport->port_name[6], fcport->port_name[7], rval, | ||
| 2168 | port_speed, mb[0], mb[1])); | ||
| 2169 | } else { | ||
| 2170 | DEBUG2(qla_printk(KERN_INFO, ha, | ||
| 2171 | "iIDMA adjusted to %s GB/s on " | ||
| 2172 | "%02x%02x%02x%02x%02x%02x%02x%02x.\n", | ||
| 2173 | link_speeds[port_speed], fcport->port_name[0], | ||
| 2174 | fcport->port_name[1], fcport->port_name[2], | ||
| 2175 | fcport->port_name[3], fcport->port_name[4], | ||
| 2176 | fcport->port_name[5], fcport->port_name[6], | ||
| 2177 | fcport->port_name[7])); | ||
| 2178 | } | ||
| 2179 | } | ||
| 2180 | |||
| 2112 | /* | 2181 | /* |
| 2113 | * qla2x00_update_fcport | 2182 | * qla2x00_update_fcport |
| 2114 | * Updates device on list. | 2183 | * Updates device on list. |
| @@ -2135,6 +2204,8 @@ qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) | |||
| 2135 | PORT_RETRY_TIME); | 2204 | PORT_RETRY_TIME); |
| 2136 | fcport->flags &= ~FCF_LOGIN_NEEDED; | 2205 | fcport->flags &= ~FCF_LOGIN_NEEDED; |
| 2137 | 2206 | ||
| 2207 | qla2x00_iidma_fcport(ha, fcport); | ||
| 2208 | |||
| 2138 | atomic_set(&fcport->state, FCS_ONLINE); | 2209 | atomic_set(&fcport->state, FCS_ONLINE); |
| 2139 | 2210 | ||
| 2140 | if (ha->flags.init_done) | 2211 | if (ha->flags.init_done) |
| @@ -2416,6 +2487,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) | |||
| 2416 | } else if (qla2x00_gnn_id(ha, swl) != QLA_SUCCESS) { | 2487 | } else if (qla2x00_gnn_id(ha, swl) != QLA_SUCCESS) { |
| 2417 | kfree(swl); | 2488 | kfree(swl); |
| 2418 | swl = NULL; | 2489 | swl = NULL; |
| 2490 | } else if (qla2x00_gfpn_id(ha, swl) == QLA_SUCCESS) { | ||
| 2491 | qla2x00_gpsc(ha, swl); | ||
| 2419 | } | 2492 | } |
| 2420 | } | 2493 | } |
| 2421 | swl_idx = 0; | 2494 | swl_idx = 0; |
| @@ -2450,6 +2523,9 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) | |||
| 2450 | swl[swl_idx].node_name, WWN_SIZE); | 2523 | swl[swl_idx].node_name, WWN_SIZE); |
| 2451 | memcpy(new_fcport->port_name, | 2524 | memcpy(new_fcport->port_name, |
| 2452 | swl[swl_idx].port_name, WWN_SIZE); | 2525 | swl[swl_idx].port_name, WWN_SIZE); |
| 2526 | memcpy(new_fcport->fabric_port_name, | ||
| 2527 | swl[swl_idx].fabric_port_name, WWN_SIZE); | ||
| 2528 | new_fcport->fp_speed = swl[swl_idx].fp_speed; | ||
| 2453 | 2529 | ||
| 2454 | if (swl[swl_idx].d_id.b.rsvd_1 != 0) { | 2530 | if (swl[swl_idx].d_id.b.rsvd_1 != 0) { |
| 2455 | last_dev = 1; | 2531 | last_dev = 1; |
| @@ -2507,6 +2583,11 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) | |||
| 2507 | 2583 | ||
| 2508 | found++; | 2584 | found++; |
| 2509 | 2585 | ||
| 2586 | /* Update port state. */ | ||
| 2587 | memcpy(fcport->fabric_port_name, | ||
| 2588 | new_fcport->fabric_port_name, WWN_SIZE); | ||
| 2589 | fcport->fp_speed = new_fcport->fp_speed; | ||
| 2590 | |||
| 2510 | /* | 2591 | /* |
| 2511 | * If address the same and state FCS_ONLINE, nothing | 2592 | * If address the same and state FCS_ONLINE, nothing |
| 2512 | * changed. | 2593 | * changed. |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index de0613135f70..5fa933cda992 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
| @@ -400,7 +400,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
| 400 | case MBA_LOOP_UP: /* Loop Up Event */ | 400 | case MBA_LOOP_UP: /* Loop Up Event */ |
| 401 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { | 401 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { |
| 402 | link_speed = link_speeds[0]; | 402 | link_speed = link_speeds[0]; |
| 403 | ha->link_data_rate = LDR_1GB; | 403 | ha->link_data_rate = PORT_SPEED_1GB; |
| 404 | } else { | 404 | } else { |
| 405 | link_speed = link_speeds[LS_UNKNOWN]; | 405 | link_speed = link_speeds[LS_UNKNOWN]; |
| 406 | if (mb[1] < 5) | 406 | if (mb[1] < 5) |
| @@ -429,7 +429,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
| 429 | } | 429 | } |
| 430 | 430 | ||
| 431 | ha->flags.management_server_logged_in = 0; | 431 | ha->flags.management_server_logged_in = 0; |
| 432 | ha->link_data_rate = LDR_UNKNOWN; | 432 | ha->link_data_rate = PORT_SPEED_UNKNOWN; |
| 433 | if (ql2xfdmienable) | 433 | if (ql2xfdmienable) |
| 434 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); | 434 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); |
| 435 | break; | 435 | break; |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 879f281e2ea2..4cde76c85cb3 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
| @@ -2540,3 +2540,89 @@ qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr, | |||
| 2540 | 2540 | ||
| 2541 | return rval; | 2541 | return rval; |
| 2542 | } | 2542 | } |
| 2543 | |||
| 2544 | int | ||
| 2545 | qla2x00_get_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id, | ||
| 2546 | uint16_t *port_speed, uint16_t *mb) | ||
| 2547 | { | ||
| 2548 | int rval; | ||
| 2549 | mbx_cmd_t mc; | ||
| 2550 | mbx_cmd_t *mcp = &mc; | ||
| 2551 | |||
| 2552 | if (!IS_QLA24XX(ha)) | ||
| 2553 | return QLA_FUNCTION_FAILED; | ||
| 2554 | |||
| 2555 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | ||
| 2556 | |||
| 2557 | mcp->mb[0] = MBC_PORT_PARAMS; | ||
| 2558 | mcp->mb[1] = loop_id; | ||
| 2559 | mcp->mb[2] = mcp->mb[3] = mcp->mb[4] = mcp->mb[5] = 0; | ||
| 2560 | mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | ||
| 2561 | mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; | ||
| 2562 | mcp->tov = 30; | ||
| 2563 | mcp->flags = 0; | ||
| 2564 | rval = qla2x00_mailbox_command(ha, mcp); | ||
| 2565 | |||
| 2566 | /* Return mailbox statuses. */ | ||
| 2567 | if (mb != NULL) { | ||
| 2568 | mb[0] = mcp->mb[0]; | ||
| 2569 | mb[1] = mcp->mb[1]; | ||
| 2570 | mb[3] = mcp->mb[3]; | ||
| 2571 | mb[4] = mcp->mb[4]; | ||
| 2572 | mb[5] = mcp->mb[5]; | ||
| 2573 | } | ||
| 2574 | |||
| 2575 | if (rval != QLA_SUCCESS) { | ||
| 2576 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, | ||
| 2577 | ha->host_no, rval)); | ||
| 2578 | } else { | ||
| 2579 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
| 2580 | if (port_speed) | ||
| 2581 | *port_speed = mcp->mb[3]; | ||
| 2582 | } | ||
| 2583 | |||
| 2584 | return rval; | ||
| 2585 | } | ||
| 2586 | |||
| 2587 | int | ||
| 2588 | qla2x00_set_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id, | ||
| 2589 | uint16_t port_speed, uint16_t *mb) | ||
| 2590 | { | ||
| 2591 | int rval; | ||
| 2592 | mbx_cmd_t mc; | ||
| 2593 | mbx_cmd_t *mcp = &mc; | ||
| 2594 | |||
| 2595 | if (!IS_QLA24XX(ha)) | ||
| 2596 | return QLA_FUNCTION_FAILED; | ||
| 2597 | |||
| 2598 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | ||
| 2599 | |||
| 2600 | mcp->mb[0] = MBC_PORT_PARAMS; | ||
| 2601 | mcp->mb[1] = loop_id; | ||
| 2602 | mcp->mb[2] = BIT_0; | ||
| 2603 | mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0); | ||
| 2604 | mcp->mb[4] = mcp->mb[5] = 0; | ||
| 2605 | mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | ||
| 2606 | mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; | ||
| 2607 | mcp->tov = 30; | ||
| 2608 | mcp->flags = 0; | ||
| 2609 | rval = qla2x00_mailbox_command(ha, mcp); | ||
| 2610 | |||
| 2611 | /* Return mailbox statuses. */ | ||
| 2612 | if (mb != NULL) { | ||
| 2613 | mb[0] = mcp->mb[0]; | ||
| 2614 | mb[1] = mcp->mb[1]; | ||
| 2615 | mb[3] = mcp->mb[3]; | ||
| 2616 | mb[4] = mcp->mb[4]; | ||
| 2617 | mb[5] = mcp->mb[5]; | ||
| 2618 | } | ||
| 2619 | |||
| 2620 | if (rval != QLA_SUCCESS) { | ||
| 2621 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, | ||
| 2622 | ha->host_no, rval)); | ||
| 2623 | } else { | ||
| 2624 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
| 2625 | } | ||
| 2626 | |||
| 2627 | return rval; | ||
| 2628 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 65cbe2f5eea2..9e665e1281c4 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
| @@ -1385,7 +1385,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 1385 | ha->prev_topology = 0; | 1385 | ha->prev_topology = 0; |
| 1386 | ha->init_cb_size = sizeof(init_cb_t); | 1386 | ha->init_cb_size = sizeof(init_cb_t); |
| 1387 | ha->mgmt_svr_loop_id = MANAGEMENT_SERVER; | 1387 | ha->mgmt_svr_loop_id = MANAGEMENT_SERVER; |
| 1388 | ha->link_data_rate = LDR_UNKNOWN; | 1388 | ha->link_data_rate = PORT_SPEED_UNKNOWN; |
| 1389 | ha->optrom_size = OPTROM_SIZE_2300; | 1389 | ha->optrom_size = OPTROM_SIZE_2300; |
| 1390 | 1390 | ||
| 1391 | /* Assign ISP specific operations. */ | 1391 | /* Assign ISP specific operations. */ |
