aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2006-10-02 15:00:43 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-10-03 18:28:38 -0400
commitd8b4521349274ab610d0b29384c704444e55cbca (patch)
tree5af421c4c6c262e966e2e3f37241b1cdb4fa199a
parentee0ca6bab394fe41a2b4de58c4532b09a41c9165 (diff)
[SCSI] qla2xxx: Add iIDMA support.
iIDMA (Intelligent Interleaved Direct Memory Access) allows for the HBA hardware to send FC frames at the rate at which they can be received by a target device. By taking advantage of the higher link rate, the HBA can maximize bandwidth utilization in a heterogeneous multi-speed SAN. Within a fabric topology, port speed detection is done via a Name Server command (GFPN_ID) followed by a Fabric Management command (GPSC). In an FCAL/N2N topology, port speed is based on the HBA link-rate. Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c6
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h39
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h8
-rw-r--r--drivers/scsi/qla2xxx/qla_gs.c187
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c81
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c86
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c2
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);
208extern int 208extern int
209qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t); 209qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t);
210 210
211extern int
212qla2x00_get_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t *, uint16_t *);
213
214extern int
215qla2x00_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 *);
279extern void *qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t); 285extern void *qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
280extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t); 286extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
281extern int qla2x00_fdmi_register(scsi_qla_host_t *); 287extern int qla2x00_fdmi_register(scsi_qla_host_t *);
288extern int qla2x00_gfpn_id(scsi_qla_host_t *, sw_info_t *);
289extern 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 */
1657int
1658qla2x00_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
1712static inline void *
1713qla24xx_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
1742static inline struct ct_sns_req *
1743qla24xx_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 */
1764int
1765qla2x00_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
2125static void
2126qla2x00_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
2544int
2545qla2x00_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
2587int
2588qla2x00_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. */