| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
| Andrew Vasquez | fa90c54 | 2005-10-27 11:10:08 -0700 | [diff] [blame] | 2 |  * QLogic Fibre Channel HBA Driver | 
| Andrew Vasquez | 07e264b | 2011-03-30 11:46:23 -0700 | [diff] [blame] | 3 |  * Copyright (c)  2003-2011 QLogic Corporation | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 4 |  * | 
| Andrew Vasquez | fa90c54 | 2005-10-27 11:10:08 -0700 | [diff] [blame] | 5 |  * See LICENSE.qla2xxx for copyright and licensing details. | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 6 |  */ | 
 | 7 | #include "qla_def.h" | 
 | 8 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 9 | static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *); | 
 | 10 | static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *); | 
 | 11 | static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *); | 
 | 12 | static int qla2x00_sns_gnn_id(scsi_qla_host_t *, sw_info_t *); | 
 | 13 | static int qla2x00_sns_rft_id(scsi_qla_host_t *); | 
 | 14 | static int qla2x00_sns_rnn_id(scsi_qla_host_t *); | 
 | 15 |  | 
 | 16 | /** | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 17 |  * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query. | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 18 |  * @ha: HA context | 
 | 19 |  * @req_size: request size in bytes | 
 | 20 |  * @rsp_size: response size in bytes | 
 | 21 |  * | 
 | 22 |  * Returns a pointer to the @ha's ms_iocb. | 
 | 23 |  */ | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 24 | void * | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 25 | qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, uint32_t req_size, uint32_t rsp_size) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 26 | { | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 27 | 	struct qla_hw_data *ha = vha->hw; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 28 | 	ms_iocb_entry_t *ms_pkt; | 
 | 29 |  | 
 | 30 | 	ms_pkt = ha->ms_iocb; | 
 | 31 | 	memset(ms_pkt, 0, sizeof(ms_iocb_entry_t)); | 
 | 32 |  | 
 | 33 | 	ms_pkt->entry_type = MS_IOCB_TYPE; | 
 | 34 | 	ms_pkt->entry_count = 1; | 
 | 35 | 	SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER); | 
 | 36 | 	ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG); | 
| Andrew Vasquez | 00a537b | 2008-02-28 14:06:11 -0800 | [diff] [blame] | 37 | 	ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 38 | 	ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); | 
 | 39 | 	ms_pkt->total_dsd_count = __constant_cpu_to_le16(2); | 
 | 40 | 	ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size); | 
 | 41 | 	ms_pkt->req_bytecount = cpu_to_le32(req_size); | 
 | 42 |  | 
 | 43 | 	ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); | 
 | 44 | 	ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); | 
 | 45 | 	ms_pkt->dseg_req_length = ms_pkt->req_bytecount; | 
 | 46 |  | 
 | 47 | 	ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); | 
 | 48 | 	ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); | 
 | 49 | 	ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount; | 
 | 50 |  | 
 | 51 | 	return (ms_pkt); | 
 | 52 | } | 
 | 53 |  | 
 | 54 | /** | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 55 |  * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query. | 
 | 56 |  * @ha: HA context | 
 | 57 |  * @req_size: request size in bytes | 
 | 58 |  * @rsp_size: response size in bytes | 
 | 59 |  * | 
 | 60 |  * Returns a pointer to the @ha's ms_iocb. | 
 | 61 |  */ | 
 | 62 | void * | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 63 | qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, uint32_t req_size, uint32_t rsp_size) | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 64 | { | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 65 | 	struct qla_hw_data *ha = vha->hw; | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 66 | 	struct ct_entry_24xx *ct_pkt; | 
 | 67 |  | 
 | 68 | 	ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; | 
 | 69 | 	memset(ct_pkt, 0, sizeof(struct ct_entry_24xx)); | 
 | 70 |  | 
 | 71 | 	ct_pkt->entry_type = CT_IOCB_TYPE; | 
 | 72 | 	ct_pkt->entry_count = 1; | 
 | 73 | 	ct_pkt->nport_handle = __constant_cpu_to_le16(NPH_SNS); | 
| Andrew Vasquez | 00a537b | 2008-02-28 14:06:11 -0800 | [diff] [blame] | 74 | 	ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 75 | 	ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); | 
 | 76 | 	ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1); | 
 | 77 | 	ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); | 
 | 78 | 	ct_pkt->cmd_byte_count = cpu_to_le32(req_size); | 
 | 79 |  | 
 | 80 | 	ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); | 
 | 81 | 	ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); | 
 | 82 | 	ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; | 
 | 83 |  | 
 | 84 | 	ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); | 
 | 85 | 	ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); | 
 | 86 | 	ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 87 | 	ct_pkt->vp_index = vha->vp_idx; | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 88 |  | 
 | 89 | 	return (ct_pkt); | 
 | 90 | } | 
 | 91 |  | 
 | 92 | /** | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 93 |  * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query. | 
 | 94 |  * @ct_req: CT request buffer | 
 | 95 |  * @cmd: GS command | 
 | 96 |  * @rsp_size: response size in bytes | 
 | 97 |  * | 
 | 98 |  * Returns a pointer to the intitialized @ct_req. | 
 | 99 |  */ | 
 | 100 | static inline struct ct_sns_req * | 
 | 101 | qla2x00_prep_ct_req(struct ct_sns_req *ct_req, uint16_t cmd, uint16_t rsp_size) | 
 | 102 | { | 
 | 103 | 	memset(ct_req, 0, sizeof(struct ct_sns_pkt)); | 
 | 104 |  | 
 | 105 | 	ct_req->header.revision = 0x01; | 
 | 106 | 	ct_req->header.gs_type = 0xFC; | 
 | 107 | 	ct_req->header.gs_subtype = 0x02; | 
 | 108 | 	ct_req->command = cpu_to_be16(cmd); | 
 | 109 | 	ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); | 
 | 110 |  | 
 | 111 | 	return (ct_req); | 
 | 112 | } | 
 | 113 |  | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 114 | static int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 115 | qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt, | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 116 |     struct ct_sns_rsp *ct_rsp, const char *routine) | 
 | 117 | { | 
 | 118 | 	int rval; | 
 | 119 | 	uint16_t comp_status; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 120 | 	struct qla_hw_data *ha = vha->hw; | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 121 |  | 
 | 122 | 	rval = QLA_FUNCTION_FAILED; | 
 | 123 | 	if (ms_pkt->entry_status != 0) { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 124 | 		ql_dbg(ql_dbg_disc, vha, 0x2031, | 
 | 125 | 		    "%s failed, error status (%x) on port_id: %02x%02x%02x.\n", | 
 | 126 | 		    routine, ms_pkt->entry_status, vha->d_id.b.domain, | 
 | 127 | 		    vha->d_id.b.area, vha->d_id.b.al_pa); | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 128 | 	} else { | 
| Andrew Vasquez | e428924 | 2007-07-19 15:05:56 -0700 | [diff] [blame] | 129 | 		if (IS_FWI2_CAPABLE(ha)) | 
| Andrew Vasquez | cdfc82a | 2006-12-13 19:20:26 -0800 | [diff] [blame] | 130 | 			comp_status = le16_to_cpu( | 
 | 131 | 			    ((struct ct_entry_24xx *)ms_pkt)->comp_status); | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 132 | 		else | 
 | 133 | 			comp_status = le16_to_cpu(ms_pkt->status); | 
 | 134 | 		switch (comp_status) { | 
 | 135 | 		case CS_COMPLETE: | 
 | 136 | 		case CS_DATA_UNDERRUN: | 
 | 137 | 		case CS_DATA_OVERRUN:		/* Overrun? */ | 
 | 138 | 			if (ct_rsp->header.response != | 
 | 139 | 			    __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 140 | 				ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2077, | 
 | 141 | 				    "%s failed rejected request on port_id: " | 
 | 142 | 				    "%02x%02x%02x.\n", routine, | 
| Giridhar Malavali | cf2d771 | 2011-02-23 15:27:09 -0800 | [diff] [blame] | 143 | 				    vha->d_id.b.domain, vha->d_id.b.area, | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 144 | 				    vha->d_id.b.al_pa); | 
 | 145 | 				ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, | 
 | 146 | 				    0x2078, (uint8_t *)&ct_rsp->header, | 
 | 147 | 				    sizeof(struct ct_rsp_hdr)); | 
| Andrew Vasquez | 4346b14 | 2006-12-13 19:20:28 -0800 | [diff] [blame] | 148 | 				rval = QLA_INVALID_COMMAND; | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 149 | 			} else | 
 | 150 | 				rval = QLA_SUCCESS; | 
 | 151 | 			break; | 
 | 152 | 		default: | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 153 | 			ql_dbg(ql_dbg_disc, vha, 0x2033, | 
 | 154 | 			    "%s failed, completion status (%x) on port_id: " | 
 | 155 | 			    "%02x%02x%02x.\n", routine, comp_status, | 
| Giridhar Malavali | cf2d771 | 2011-02-23 15:27:09 -0800 | [diff] [blame] | 156 | 			    vha->d_id.b.domain, vha->d_id.b.area, | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 157 | 			    vha->d_id.b.al_pa); | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 158 | 			break; | 
 | 159 | 		} | 
 | 160 | 	} | 
 | 161 | 	return rval; | 
 | 162 | } | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 163 |  | 
 | 164 | /** | 
 | 165 |  * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command. | 
 | 166 |  * @ha: HA context | 
 | 167 |  * @fcport: fcport entry to updated | 
 | 168 |  * | 
 | 169 |  * Returns 0 on success. | 
 | 170 |  */ | 
 | 171 | int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 172 | qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 173 | { | 
 | 174 | 	int		rval; | 
 | 175 |  | 
 | 176 | 	ms_iocb_entry_t	*ms_pkt; | 
 | 177 | 	struct ct_sns_req	*ct_req; | 
 | 178 | 	struct ct_sns_rsp	*ct_rsp; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 179 | 	struct qla_hw_data *ha = vha->hw; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 180 |  | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 181 | 	if (IS_QLA2100(ha) || IS_QLA2200(ha)) | 
 | 182 | 		return qla2x00_sns_ga_nxt(vha, fcport); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 183 |  | 
 | 184 | 	/* Issue GA_NXT */ | 
 | 185 | 	/* Prepare common MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 186 | 	ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GA_NXT_REQ_SIZE, | 
| Andrew Vasquez | fd34f55 | 2007-07-19 15:06:00 -0700 | [diff] [blame] | 187 | 	    GA_NXT_RSP_SIZE); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 188 |  | 
 | 189 | 	/* Prepare CT request */ | 
 | 190 | 	ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GA_NXT_CMD, | 
 | 191 | 	    GA_NXT_RSP_SIZE); | 
 | 192 | 	ct_rsp = &ha->ct_sns->p.rsp; | 
 | 193 |  | 
 | 194 | 	/* Prepare CT arguments -- port_id */ | 
 | 195 | 	ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain; | 
 | 196 | 	ct_req->req.port_id.port_id[1] = fcport->d_id.b.area; | 
 | 197 | 	ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa; | 
 | 198 |  | 
 | 199 | 	/* Execute MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 200 | 	rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 201 | 	    sizeof(ms_iocb_entry_t)); | 
 | 202 | 	if (rval != QLA_SUCCESS) { | 
 | 203 | 		/*EMPTY*/ | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 204 | 		ql_dbg(ql_dbg_disc, vha, 0x2062, | 
 | 205 | 		    "GA_NXT issue IOCB failed (%d).\n", rval); | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 206 | 	} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GA_NXT") != | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 207 | 	    QLA_SUCCESS) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 208 | 		rval = QLA_FUNCTION_FAILED; | 
 | 209 | 	} else { | 
 | 210 | 		/* Populate fc_port_t entry. */ | 
 | 211 | 		fcport->d_id.b.domain = ct_rsp->rsp.ga_nxt.port_id[0]; | 
 | 212 | 		fcport->d_id.b.area = ct_rsp->rsp.ga_nxt.port_id[1]; | 
 | 213 | 		fcport->d_id.b.al_pa = ct_rsp->rsp.ga_nxt.port_id[2]; | 
 | 214 |  | 
 | 215 | 		memcpy(fcport->node_name, ct_rsp->rsp.ga_nxt.node_name, | 
 | 216 | 		    WWN_SIZE); | 
 | 217 | 		memcpy(fcport->port_name, ct_rsp->rsp.ga_nxt.port_name, | 
 | 218 | 		    WWN_SIZE); | 
 | 219 |  | 
 | 220 | 		if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE && | 
 | 221 | 		    ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE) | 
 | 222 | 			fcport->d_id.b.domain = 0xf0; | 
 | 223 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 224 | 		ql_dbg(ql_dbg_disc, vha, 0x2063, | 
 | 225 | 		    "GA_NXT entry - nn %02x%02x%02x%02x%02x%02x%02x%02x " | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 226 | 		    "pn %02x%02x%02x%02x%02x%02x%02x%02x " | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 227 | 		    "port_id=%02x%02x%02x.\n", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 228 | 		    fcport->node_name[0], fcport->node_name[1], | 
 | 229 | 		    fcport->node_name[2], fcport->node_name[3], | 
 | 230 | 		    fcport->node_name[4], fcport->node_name[5], | 
 | 231 | 		    fcport->node_name[6], fcport->node_name[7], | 
 | 232 | 		    fcport->port_name[0], fcport->port_name[1], | 
 | 233 | 		    fcport->port_name[2], fcport->port_name[3], | 
 | 234 | 		    fcport->port_name[4], fcport->port_name[5], | 
 | 235 | 		    fcport->port_name[6], fcport->port_name[7], | 
 | 236 | 		    fcport->d_id.b.domain, fcport->d_id.b.area, | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 237 | 		    fcport->d_id.b.al_pa); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 238 | 	} | 
 | 239 |  | 
 | 240 | 	return (rval); | 
 | 241 | } | 
 | 242 |  | 
 | 243 | /** | 
 | 244 |  * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command. | 
 | 245 |  * @ha: HA context | 
 | 246 |  * @list: switch info entries to populate | 
 | 247 |  * | 
 | 248 |  * NOTE: Non-Nx_Ports are not requested. | 
 | 249 |  * | 
 | 250 |  * Returns 0 on success. | 
 | 251 |  */ | 
 | 252 | int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 253 | qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 254 | { | 
 | 255 | 	int		rval; | 
 | 256 | 	uint16_t	i; | 
 | 257 |  | 
 | 258 | 	ms_iocb_entry_t	*ms_pkt; | 
 | 259 | 	struct ct_sns_req	*ct_req; | 
 | 260 | 	struct ct_sns_rsp	*ct_rsp; | 
 | 261 |  | 
 | 262 | 	struct ct_sns_gid_pt_data *gid_data; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 263 | 	struct qla_hw_data *ha = vha->hw; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 264 |  | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 265 | 	if (IS_QLA2100(ha) || IS_QLA2200(ha)) | 
 | 266 | 		return qla2x00_sns_gid_pt(vha, list); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 267 |  | 
 | 268 | 	gid_data = NULL; | 
 | 269 |  | 
 | 270 | 	/* Issue GID_PT */ | 
 | 271 | 	/* Prepare common MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 272 | 	ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GID_PT_REQ_SIZE, | 
| Andrew Vasquez | fd34f55 | 2007-07-19 15:06:00 -0700 | [diff] [blame] | 273 | 	    GID_PT_RSP_SIZE); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 274 |  | 
 | 275 | 	/* Prepare CT request */ | 
 | 276 | 	ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GID_PT_CMD, | 
 | 277 | 	    GID_PT_RSP_SIZE); | 
 | 278 | 	ct_rsp = &ha->ct_sns->p.rsp; | 
 | 279 |  | 
 | 280 | 	/* Prepare CT arguments -- port_type */ | 
 | 281 | 	ct_req->req.gid_pt.port_type = NS_NX_PORT_TYPE; | 
 | 282 |  | 
 | 283 | 	/* Execute MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 284 | 	rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 285 | 	    sizeof(ms_iocb_entry_t)); | 
 | 286 | 	if (rval != QLA_SUCCESS) { | 
 | 287 | 		/*EMPTY*/ | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 288 | 		ql_dbg(ql_dbg_disc, vha, 0x2055, | 
 | 289 | 		    "GID_PT issue IOCB failed (%d).\n", rval); | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 290 | 	} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GID_PT") != | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 291 | 	    QLA_SUCCESS) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 292 | 		rval = QLA_FUNCTION_FAILED; | 
 | 293 | 	} else { | 
 | 294 | 		/* Set port IDs in switch info list. */ | 
 | 295 | 		for (i = 0; i < MAX_FIBRE_DEVICES; i++) { | 
 | 296 | 			gid_data = &ct_rsp->rsp.gid_pt.entries[i]; | 
 | 297 | 			list[i].d_id.b.domain = gid_data->port_id[0]; | 
 | 298 | 			list[i].d_id.b.area = gid_data->port_id[1]; | 
 | 299 | 			list[i].d_id.b.al_pa = gid_data->port_id[2]; | 
| Andrew Vasquez | a3cbdfa | 2007-08-13 10:13:18 -0700 | [diff] [blame] | 300 | 			memset(list[i].fabric_port_name, 0, WWN_SIZE); | 
 | 301 | 			list[i].fp_speed = PORT_SPEED_UNKNOWN; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 302 |  | 
 | 303 | 			/* Last one exit. */ | 
 | 304 | 			if (gid_data->control_byte & BIT_7) { | 
 | 305 | 				list[i].d_id.b.rsvd_1 = gid_data->control_byte; | 
 | 306 | 				break; | 
 | 307 | 			} | 
 | 308 | 		} | 
 | 309 |  | 
 | 310 | 		/* | 
 | 311 | 		 * If we've used all available slots, then the switch is | 
 | 312 | 		 * reporting back more devices than we can handle with this | 
 | 313 | 		 * single call.  Return a failed status, and let GA_NXT handle | 
 | 314 | 		 * the overload. | 
 | 315 | 		 */ | 
| Andrew Vasquez | fa2a1ce | 2005-07-06 10:32:07 -0700 | [diff] [blame] | 316 | 		if (i == MAX_FIBRE_DEVICES) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 317 | 			rval = QLA_FUNCTION_FAILED; | 
 | 318 | 	} | 
 | 319 |  | 
 | 320 | 	return (rval); | 
 | 321 | } | 
 | 322 |  | 
 | 323 | /** | 
 | 324 |  * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query. | 
 | 325 |  * @ha: HA context | 
 | 326 |  * @list: switch info entries to populate | 
 | 327 |  * | 
 | 328 |  * Returns 0 on success. | 
 | 329 |  */ | 
 | 330 | int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 331 | qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 332 | { | 
 | 333 | 	int		rval; | 
 | 334 | 	uint16_t	i; | 
 | 335 |  | 
 | 336 | 	ms_iocb_entry_t	*ms_pkt; | 
 | 337 | 	struct ct_sns_req	*ct_req; | 
 | 338 | 	struct ct_sns_rsp	*ct_rsp; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 339 | 	struct qla_hw_data *ha = vha->hw; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 340 |  | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 341 | 	if (IS_QLA2100(ha) || IS_QLA2200(ha)) | 
 | 342 | 		return qla2x00_sns_gpn_id(vha, list); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 343 |  | 
 | 344 | 	for (i = 0; i < MAX_FIBRE_DEVICES; i++) { | 
 | 345 | 		/* Issue GPN_ID */ | 
 | 346 | 		/* Prepare common MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 347 | 		ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GPN_ID_REQ_SIZE, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 348 | 		    GPN_ID_RSP_SIZE); | 
 | 349 |  | 
 | 350 | 		/* Prepare CT request */ | 
 | 351 | 		ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GPN_ID_CMD, | 
 | 352 | 		    GPN_ID_RSP_SIZE); | 
 | 353 | 		ct_rsp = &ha->ct_sns->p.rsp; | 
 | 354 |  | 
 | 355 | 		/* Prepare CT arguments -- port_id */ | 
 | 356 | 		ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; | 
 | 357 | 		ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; | 
 | 358 | 		ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; | 
 | 359 |  | 
 | 360 | 		/* Execute MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 361 | 		rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 362 | 		    sizeof(ms_iocb_entry_t)); | 
 | 363 | 		if (rval != QLA_SUCCESS) { | 
 | 364 | 			/*EMPTY*/ | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 365 | 			ql_dbg(ql_dbg_disc, vha, 0x2056, | 
 | 366 | 			    "GPN_ID issue IOCB failed (%d).\n", rval); | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 367 | 		} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 368 | 		    "GPN_ID") != QLA_SUCCESS) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 369 | 			rval = QLA_FUNCTION_FAILED; | 
 | 370 | 		} else { | 
 | 371 | 			/* Save portname */ | 
 | 372 | 			memcpy(list[i].port_name, | 
 | 373 | 			    ct_rsp->rsp.gpn_id.port_name, WWN_SIZE); | 
 | 374 | 		} | 
 | 375 |  | 
 | 376 | 		/* Last device exit. */ | 
 | 377 | 		if (list[i].d_id.b.rsvd_1 != 0) | 
 | 378 | 			break; | 
 | 379 | 	} | 
 | 380 |  | 
 | 381 | 	return (rval); | 
 | 382 | } | 
 | 383 |  | 
 | 384 | /** | 
 | 385 |  * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query. | 
 | 386 |  * @ha: HA context | 
 | 387 |  * @list: switch info entries to populate | 
 | 388 |  * | 
 | 389 |  * Returns 0 on success. | 
 | 390 |  */ | 
 | 391 | int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 392 | qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 393 | { | 
 | 394 | 	int		rval; | 
 | 395 | 	uint16_t	i; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 396 | 	struct qla_hw_data *ha = vha->hw; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 397 | 	ms_iocb_entry_t	*ms_pkt; | 
 | 398 | 	struct ct_sns_req	*ct_req; | 
 | 399 | 	struct ct_sns_rsp	*ct_rsp; | 
 | 400 |  | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 401 | 	if (IS_QLA2100(ha) || IS_QLA2200(ha)) | 
 | 402 | 		return qla2x00_sns_gnn_id(vha, list); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 403 |  | 
 | 404 | 	for (i = 0; i < MAX_FIBRE_DEVICES; i++) { | 
 | 405 | 		/* Issue GNN_ID */ | 
 | 406 | 		/* Prepare common MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 407 | 		ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GNN_ID_REQ_SIZE, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 408 | 		    GNN_ID_RSP_SIZE); | 
 | 409 |  | 
 | 410 | 		/* Prepare CT request */ | 
 | 411 | 		ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GNN_ID_CMD, | 
 | 412 | 		    GNN_ID_RSP_SIZE); | 
 | 413 | 		ct_rsp = &ha->ct_sns->p.rsp; | 
 | 414 |  | 
 | 415 | 		/* Prepare CT arguments -- port_id */ | 
 | 416 | 		ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; | 
 | 417 | 		ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; | 
 | 418 | 		ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; | 
 | 419 |  | 
 | 420 | 		/* Execute MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 421 | 		rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 422 | 		    sizeof(ms_iocb_entry_t)); | 
 | 423 | 		if (rval != QLA_SUCCESS) { | 
 | 424 | 			/*EMPTY*/ | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 425 | 			ql_dbg(ql_dbg_disc, vha, 0x2057, | 
 | 426 | 			    "GNN_ID issue IOCB failed (%d).\n", rval); | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 427 | 		} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 428 | 		    "GNN_ID") != QLA_SUCCESS) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 429 | 			rval = QLA_FUNCTION_FAILED; | 
 | 430 | 		} else { | 
 | 431 | 			/* Save nodename */ | 
 | 432 | 			memcpy(list[i].node_name, | 
 | 433 | 			    ct_rsp->rsp.gnn_id.node_name, WWN_SIZE); | 
 | 434 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 435 | 			ql_dbg(ql_dbg_disc, vha, 0x2058, | 
 | 436 | 			    "GID_PT entry - nn %02x%02x%02x%02x%02x%02x%02X%02x " | 
 | 437 | 			    "pn %02x%02x%02x%02x%02x%02x%02X%02x " | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 438 | 			    "portid=%02x%02x%02x.\n", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 439 | 			    list[i].node_name[0], list[i].node_name[1], | 
 | 440 | 			    list[i].node_name[2], list[i].node_name[3], | 
 | 441 | 			    list[i].node_name[4], list[i].node_name[5], | 
 | 442 | 			    list[i].node_name[6], list[i].node_name[7], | 
 | 443 | 			    list[i].port_name[0], list[i].port_name[1], | 
 | 444 | 			    list[i].port_name[2], list[i].port_name[3], | 
 | 445 | 			    list[i].port_name[4], list[i].port_name[5], | 
 | 446 | 			    list[i].port_name[6], list[i].port_name[7], | 
 | 447 | 			    list[i].d_id.b.domain, list[i].d_id.b.area, | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 448 | 			    list[i].d_id.b.al_pa); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 449 | 		} | 
 | 450 |  | 
 | 451 | 		/* Last device exit. */ | 
 | 452 | 		if (list[i].d_id.b.rsvd_1 != 0) | 
 | 453 | 			break; | 
 | 454 | 	} | 
 | 455 |  | 
 | 456 | 	return (rval); | 
 | 457 | } | 
 | 458 |  | 
 | 459 | /** | 
 | 460 |  * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. | 
 | 461 |  * @ha: HA context | 
 | 462 |  * | 
 | 463 |  * Returns 0 on success. | 
 | 464 |  */ | 
 | 465 | int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 466 | qla2x00_rft_id(scsi_qla_host_t *vha) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 467 | { | 
 | 468 | 	int		rval; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 469 | 	struct qla_hw_data *ha = vha->hw; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 470 | 	ms_iocb_entry_t	*ms_pkt; | 
 | 471 | 	struct ct_sns_req	*ct_req; | 
 | 472 | 	struct ct_sns_rsp	*ct_rsp; | 
 | 473 |  | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 474 | 	if (IS_QLA2100(ha) || IS_QLA2200(ha)) | 
 | 475 | 		return qla2x00_sns_rft_id(vha); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 476 |  | 
 | 477 | 	/* Issue RFT_ID */ | 
 | 478 | 	/* Prepare common MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 479 | 	ms_pkt = ha->isp_ops->prep_ms_iocb(vha, RFT_ID_REQ_SIZE, | 
| Andrew Vasquez | fd34f55 | 2007-07-19 15:06:00 -0700 | [diff] [blame] | 480 | 	    RFT_ID_RSP_SIZE); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 481 |  | 
 | 482 | 	/* Prepare CT request */ | 
 | 483 | 	ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFT_ID_CMD, | 
 | 484 | 	    RFT_ID_RSP_SIZE); | 
 | 485 | 	ct_rsp = &ha->ct_sns->p.rsp; | 
 | 486 |  | 
 | 487 | 	/* Prepare CT arguments -- port_id, FC-4 types */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 488 | 	ct_req->req.rft_id.port_id[0] = vha->d_id.b.domain; | 
 | 489 | 	ct_req->req.rft_id.port_id[1] = vha->d_id.b.area; | 
 | 490 | 	ct_req->req.rft_id.port_id[2] = vha->d_id.b.al_pa; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 491 |  | 
 | 492 | 	ct_req->req.rft_id.fc4_types[2] = 0x01;		/* FCP-3 */ | 
 | 493 |  | 
 | 494 | 	/* Execute MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 495 | 	rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 496 | 	    sizeof(ms_iocb_entry_t)); | 
 | 497 | 	if (rval != QLA_SUCCESS) { | 
 | 498 | 		/*EMPTY*/ | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 499 | 		ql_dbg(ql_dbg_disc, vha, 0x2043, | 
 | 500 | 		    "RFT_ID issue IOCB failed (%d).\n", rval); | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 501 | 	} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RFT_ID") != | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 502 | 	    QLA_SUCCESS) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 503 | 		rval = QLA_FUNCTION_FAILED; | 
 | 504 | 	} else { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 505 | 		ql_dbg(ql_dbg_disc, vha, 0x2044, | 
 | 506 | 		    "RFT_ID exiting normally.\n"); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 507 | 	} | 
 | 508 |  | 
 | 509 | 	return (rval); | 
 | 510 | } | 
 | 511 |  | 
 | 512 | /** | 
 | 513 |  * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA. | 
 | 514 |  * @ha: HA context | 
 | 515 |  * | 
 | 516 |  * Returns 0 on success. | 
 | 517 |  */ | 
 | 518 | int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 519 | qla2x00_rff_id(scsi_qla_host_t *vha) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 520 | { | 
 | 521 | 	int		rval; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 522 | 	struct qla_hw_data *ha = vha->hw; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 523 | 	ms_iocb_entry_t	*ms_pkt; | 
 | 524 | 	struct ct_sns_req	*ct_req; | 
 | 525 | 	struct ct_sns_rsp	*ct_rsp; | 
 | 526 |  | 
 | 527 | 	if (IS_QLA2100(ha) || IS_QLA2200(ha)) { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 528 | 		ql_dbg(ql_dbg_disc, vha, 0x2046, | 
 | 529 | 		    "RFF_ID call not supported on ISP2100/ISP2200.\n"); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 530 | 		return (QLA_SUCCESS); | 
 | 531 | 	} | 
 | 532 |  | 
 | 533 | 	/* Issue RFF_ID */ | 
 | 534 | 	/* Prepare common MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 535 | 	ms_pkt = ha->isp_ops->prep_ms_iocb(vha, RFF_ID_REQ_SIZE, | 
| Andrew Vasquez | fd34f55 | 2007-07-19 15:06:00 -0700 | [diff] [blame] | 536 | 	    RFF_ID_RSP_SIZE); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 537 |  | 
 | 538 | 	/* Prepare CT request */ | 
 | 539 | 	ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFF_ID_CMD, | 
 | 540 | 	    RFF_ID_RSP_SIZE); | 
 | 541 | 	ct_rsp = &ha->ct_sns->p.rsp; | 
 | 542 |  | 
 | 543 | 	/* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 544 | 	ct_req->req.rff_id.port_id[0] = vha->d_id.b.domain; | 
 | 545 | 	ct_req->req.rff_id.port_id[1] = vha->d_id.b.area; | 
 | 546 | 	ct_req->req.rff_id.port_id[2] = vha->d_id.b.al_pa; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 547 |  | 
| andrew.vasquez@qlogic.com | 9403688 | 2006-01-13 17:04:54 -0800 | [diff] [blame] | 548 | 	ct_req->req.rff_id.fc4_feature = BIT_1; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 549 | 	ct_req->req.rff_id.fc4_type = 0x08;		/* SCSI - FCP */ | 
 | 550 |  | 
 | 551 | 	/* Execute MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 552 | 	rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 553 | 	    sizeof(ms_iocb_entry_t)); | 
 | 554 | 	if (rval != QLA_SUCCESS) { | 
 | 555 | 		/*EMPTY*/ | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 556 | 		ql_dbg(ql_dbg_disc, vha, 0x2047, | 
 | 557 | 		    "RFF_ID issue IOCB failed (%d).\n", rval); | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 558 | 	} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RFF_ID") != | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 559 | 	    QLA_SUCCESS) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 560 | 		rval = QLA_FUNCTION_FAILED; | 
 | 561 | 	} else { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 562 | 		ql_dbg(ql_dbg_disc, vha, 0x2048, | 
 | 563 | 		    "RFF_ID exiting normally.\n"); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 564 | 	} | 
 | 565 |  | 
 | 566 | 	return (rval); | 
 | 567 | } | 
 | 568 |  | 
 | 569 | /** | 
 | 570 |  * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA. | 
 | 571 |  * @ha: HA context | 
 | 572 |  * | 
 | 573 |  * Returns 0 on success. | 
 | 574 |  */ | 
 | 575 | int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 576 | qla2x00_rnn_id(scsi_qla_host_t *vha) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 577 | { | 
 | 578 | 	int		rval; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 579 | 	struct qla_hw_data *ha = vha->hw; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 580 | 	ms_iocb_entry_t	*ms_pkt; | 
 | 581 | 	struct ct_sns_req	*ct_req; | 
 | 582 | 	struct ct_sns_rsp	*ct_rsp; | 
 | 583 |  | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 584 | 	if (IS_QLA2100(ha) || IS_QLA2200(ha)) | 
 | 585 | 		return qla2x00_sns_rnn_id(vha); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 586 |  | 
 | 587 | 	/* Issue RNN_ID */ | 
 | 588 | 	/* Prepare common MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 589 | 	ms_pkt = ha->isp_ops->prep_ms_iocb(vha, RNN_ID_REQ_SIZE, | 
| Andrew Vasquez | fd34f55 | 2007-07-19 15:06:00 -0700 | [diff] [blame] | 590 | 	    RNN_ID_RSP_SIZE); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 591 |  | 
 | 592 | 	/* Prepare CT request */ | 
 | 593 | 	ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RNN_ID_CMD, | 
 | 594 | 	    RNN_ID_RSP_SIZE); | 
 | 595 | 	ct_rsp = &ha->ct_sns->p.rsp; | 
 | 596 |  | 
 | 597 | 	/* Prepare CT arguments -- port_id, node_name */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 598 | 	ct_req->req.rnn_id.port_id[0] = vha->d_id.b.domain; | 
 | 599 | 	ct_req->req.rnn_id.port_id[1] = vha->d_id.b.area; | 
 | 600 | 	ct_req->req.rnn_id.port_id[2] = vha->d_id.b.al_pa; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 601 |  | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 602 | 	memcpy(ct_req->req.rnn_id.node_name, vha->node_name, WWN_SIZE); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 603 |  | 
 | 604 | 	/* Execute MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 605 | 	rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 606 | 	    sizeof(ms_iocb_entry_t)); | 
 | 607 | 	if (rval != QLA_SUCCESS) { | 
 | 608 | 		/*EMPTY*/ | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 609 | 		ql_dbg(ql_dbg_disc, vha, 0x204d, | 
 | 610 | 		    "RNN_ID issue IOCB failed (%d).\n", rval); | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 611 | 	} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RNN_ID") != | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 612 | 	    QLA_SUCCESS) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 613 | 		rval = QLA_FUNCTION_FAILED; | 
 | 614 | 	} else { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 615 | 		ql_dbg(ql_dbg_disc, vha, 0x204e, | 
 | 616 | 		    "RNN_ID exiting normally.\n"); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 617 | 	} | 
 | 618 |  | 
 | 619 | 	return (rval); | 
 | 620 | } | 
 | 621 |  | 
| Andrew Vasquez | 1620f7c | 2006-10-02 12:00:44 -0700 | [diff] [blame] | 622 | void | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 623 | qla2x00_get_sym_node_name(scsi_qla_host_t *vha, uint8_t *snn) | 
| Andrew Vasquez | 1620f7c | 2006-10-02 12:00:44 -0700 | [diff] [blame] | 624 | { | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 625 | 	struct qla_hw_data *ha = vha->hw; | 
| Andrew Vasquez | 1620f7c | 2006-10-02 12:00:44 -0700 | [diff] [blame] | 626 | 	sprintf(snn, "%s FW:v%d.%02d.%02d DVR:v%s",ha->model_number, | 
 | 627 | 	    ha->fw_major_version, ha->fw_minor_version, | 
 | 628 | 	    ha->fw_subminor_version, qla2x00_version_str); | 
 | 629 | } | 
 | 630 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 631 | /** | 
 | 632 |  * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA. | 
 | 633 |  * @ha: HA context | 
 | 634 |  * | 
 | 635 |  * Returns 0 on success. | 
 | 636 |  */ | 
 | 637 | int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 638 | qla2x00_rsnn_nn(scsi_qla_host_t *vha) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 639 | { | 
 | 640 | 	int		rval; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 641 | 	struct qla_hw_data *ha = vha->hw; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 642 | 	ms_iocb_entry_t	*ms_pkt; | 
 | 643 | 	struct ct_sns_req	*ct_req; | 
 | 644 | 	struct ct_sns_rsp	*ct_rsp; | 
 | 645 |  | 
 | 646 | 	if (IS_QLA2100(ha) || IS_QLA2200(ha)) { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 647 | 		ql_dbg(ql_dbg_disc, vha, 0x2050, | 
 | 648 | 		    "RSNN_ID call unsupported on ISP2100/ISP2200.\n"); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 649 | 		return (QLA_SUCCESS); | 
 | 650 | 	} | 
 | 651 |  | 
 | 652 | 	/* Issue RSNN_NN */ | 
 | 653 | 	/* Prepare common MS IOCB */ | 
 | 654 | 	/*   Request size adjusted after CT preparation */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 655 | 	ms_pkt = ha->isp_ops->prep_ms_iocb(vha, 0, RSNN_NN_RSP_SIZE); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 656 |  | 
 | 657 | 	/* Prepare CT request */ | 
 | 658 | 	ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RSNN_NN_CMD, | 
 | 659 | 	    RSNN_NN_RSP_SIZE); | 
 | 660 | 	ct_rsp = &ha->ct_sns->p.rsp; | 
 | 661 |  | 
 | 662 | 	/* Prepare CT arguments -- node_name, symbolic node_name, size */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 663 | 	memcpy(ct_req->req.rsnn_nn.node_name, vha->node_name, WWN_SIZE); | 
| Andrew Vasquez | fa2a1ce | 2005-07-06 10:32:07 -0700 | [diff] [blame] | 664 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 665 | 	/* Prepare the Symbolic Node Name */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 666 | 	qla2x00_get_sym_node_name(vha, ct_req->req.rsnn_nn.sym_node_name); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 667 |  | 
 | 668 | 	/* Calculate SNN length */ | 
| Andrew Vasquez | 1620f7c | 2006-10-02 12:00:44 -0700 | [diff] [blame] | 669 | 	ct_req->req.rsnn_nn.name_len = | 
 | 670 | 	    (uint8_t)strlen(ct_req->req.rsnn_nn.sym_node_name); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 671 |  | 
 | 672 | 	/* Update MS IOCB request */ | 
 | 673 | 	ms_pkt->req_bytecount = | 
 | 674 | 	    cpu_to_le32(24 + 1 + ct_req->req.rsnn_nn.name_len); | 
 | 675 | 	ms_pkt->dseg_req_length = ms_pkt->req_bytecount; | 
 | 676 |  | 
 | 677 | 	/* Execute MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 678 | 	rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 679 | 	    sizeof(ms_iocb_entry_t)); | 
 | 680 | 	if (rval != QLA_SUCCESS) { | 
 | 681 | 		/*EMPTY*/ | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 682 | 		ql_dbg(ql_dbg_disc, vha, 0x2051, | 
 | 683 | 		    "RSNN_NN issue IOCB failed (%d).\n", rval); | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 684 | 	} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RSNN_NN") != | 
| Andrew Vasquez | 8c958a9 | 2005-07-06 10:30:47 -0700 | [diff] [blame] | 685 | 	    QLA_SUCCESS) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 686 | 		rval = QLA_FUNCTION_FAILED; | 
 | 687 | 	} else { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 688 | 		ql_dbg(ql_dbg_disc, vha, 0x2052, | 
 | 689 | 		    "RSNN_NN exiting normally.\n"); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 690 | 	} | 
 | 691 |  | 
 | 692 | 	return (rval); | 
 | 693 | } | 
 | 694 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 695 | /** | 
 | 696 |  * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query. | 
 | 697 |  * @ha: HA context | 
 | 698 |  * @cmd: GS command | 
 | 699 |  * @scmd_len: Subcommand length | 
 | 700 |  * @data_size: response size in bytes | 
 | 701 |  * | 
 | 702 |  * Returns a pointer to the @ha's sns_cmd. | 
 | 703 |  */ | 
 | 704 | static inline struct sns_cmd_pkt * | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 705 | qla2x00_prep_sns_cmd(scsi_qla_host_t *vha, uint16_t cmd, uint16_t scmd_len, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 706 |     uint16_t data_size) | 
 | 707 | { | 
 | 708 | 	uint16_t		wc; | 
 | 709 | 	struct sns_cmd_pkt	*sns_cmd; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 710 | 	struct qla_hw_data *ha = vha->hw; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 711 |  | 
 | 712 | 	sns_cmd = ha->sns_cmd; | 
 | 713 | 	memset(sns_cmd, 0, sizeof(struct sns_cmd_pkt)); | 
 | 714 | 	wc = data_size / 2;			/* Size in 16bit words. */ | 
 | 715 | 	sns_cmd->p.cmd.buffer_length = cpu_to_le16(wc); | 
 | 716 | 	sns_cmd->p.cmd.buffer_address[0] = cpu_to_le32(LSD(ha->sns_cmd_dma)); | 
 | 717 | 	sns_cmd->p.cmd.buffer_address[1] = cpu_to_le32(MSD(ha->sns_cmd_dma)); | 
 | 718 | 	sns_cmd->p.cmd.subcommand_length = cpu_to_le16(scmd_len); | 
 | 719 | 	sns_cmd->p.cmd.subcommand = cpu_to_le16(cmd); | 
 | 720 | 	wc = (data_size - 16) / 4;		/* Size in 32bit words. */ | 
 | 721 | 	sns_cmd->p.cmd.size = cpu_to_le16(wc); | 
 | 722 |  | 
 | 723 | 	return (sns_cmd); | 
 | 724 | } | 
 | 725 |  | 
 | 726 | /** | 
 | 727 |  * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command. | 
 | 728 |  * @ha: HA context | 
 | 729 |  * @fcport: fcport entry to updated | 
 | 730 |  * | 
 | 731 |  * This command uses the old Exectute SNS Command mailbox routine. | 
 | 732 |  * | 
 | 733 |  * Returns 0 on success. | 
 | 734 |  */ | 
 | 735 | static int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 736 | qla2x00_sns_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 737 | { | 
 | 738 | 	int		rval; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 739 | 	struct qla_hw_data *ha = vha->hw; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 740 | 	struct sns_cmd_pkt	*sns_cmd; | 
 | 741 |  | 
 | 742 | 	/* Issue GA_NXT. */ | 
 | 743 | 	/* Prepare SNS command request. */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 744 | 	sns_cmd = qla2x00_prep_sns_cmd(vha, GA_NXT_CMD, GA_NXT_SNS_SCMD_LEN, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 745 | 	    GA_NXT_SNS_DATA_SIZE); | 
 | 746 |  | 
 | 747 | 	/* Prepare SNS command arguments -- port_id. */ | 
 | 748 | 	sns_cmd->p.cmd.param[0] = fcport->d_id.b.al_pa; | 
 | 749 | 	sns_cmd->p.cmd.param[1] = fcport->d_id.b.area; | 
 | 750 | 	sns_cmd->p.cmd.param[2] = fcport->d_id.b.domain; | 
 | 751 |  | 
 | 752 | 	/* Execute SNS command. */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 753 | 	rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GA_NXT_SNS_CMD_SIZE / 2, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 754 | 	    sizeof(struct sns_cmd_pkt)); | 
 | 755 | 	if (rval != QLA_SUCCESS) { | 
 | 756 | 		/*EMPTY*/ | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 757 | 		ql_dbg(ql_dbg_disc, vha, 0x205f, | 
 | 758 | 		    "GA_NXT Send SNS failed (%d).\n", rval); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 759 | 	} else if (sns_cmd->p.gan_data[8] != 0x80 || | 
 | 760 | 	    sns_cmd->p.gan_data[9] != 0x02) { | 
| Chad Dupuis | cfb0919 | 2011-11-18 09:03:07 -0800 | [diff] [blame] | 761 | 		ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2084, | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 762 | 		    "GA_NXT failed, rejected request ga_nxt_rsp:\n"); | 
 | 763 | 		ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2074, | 
 | 764 | 		    sns_cmd->p.gan_data, 16); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 765 | 		rval = QLA_FUNCTION_FAILED; | 
 | 766 | 	} else { | 
 | 767 | 		/* Populate fc_port_t entry. */ | 
 | 768 | 		fcport->d_id.b.domain = sns_cmd->p.gan_data[17]; | 
 | 769 | 		fcport->d_id.b.area = sns_cmd->p.gan_data[18]; | 
 | 770 | 		fcport->d_id.b.al_pa = sns_cmd->p.gan_data[19]; | 
 | 771 |  | 
 | 772 | 		memcpy(fcport->node_name, &sns_cmd->p.gan_data[284], WWN_SIZE); | 
 | 773 | 		memcpy(fcport->port_name, &sns_cmd->p.gan_data[20], WWN_SIZE); | 
 | 774 |  | 
 | 775 | 		if (sns_cmd->p.gan_data[16] != NS_N_PORT_TYPE && | 
 | 776 | 		    sns_cmd->p.gan_data[16] != NS_NL_PORT_TYPE) | 
 | 777 | 			fcport->d_id.b.domain = 0xf0; | 
 | 778 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 779 | 		ql_dbg(ql_dbg_disc, vha, 0x2061, | 
 | 780 | 		    "GA_NXT entry - nn %02x%02x%02x%02x%02x%02x%02x%02x " | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 781 | 		    "pn %02x%02x%02x%02x%02x%02x%02x%02x " | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 782 | 		    "port_id=%02x%02x%02x.\n", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 783 | 		    fcport->node_name[0], fcport->node_name[1], | 
 | 784 | 		    fcport->node_name[2], fcport->node_name[3], | 
 | 785 | 		    fcport->node_name[4], fcport->node_name[5], | 
 | 786 | 		    fcport->node_name[6], fcport->node_name[7], | 
 | 787 | 		    fcport->port_name[0], fcport->port_name[1], | 
 | 788 | 		    fcport->port_name[2], fcport->port_name[3], | 
 | 789 | 		    fcport->port_name[4], fcport->port_name[5], | 
 | 790 | 		    fcport->port_name[6], fcport->port_name[7], | 
 | 791 | 		    fcport->d_id.b.domain, fcport->d_id.b.area, | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 792 | 		    fcport->d_id.b.al_pa); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 793 | 	} | 
 | 794 |  | 
 | 795 | 	return (rval); | 
 | 796 | } | 
 | 797 |  | 
 | 798 | /** | 
 | 799 |  * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command. | 
 | 800 |  * @ha: HA context | 
 | 801 |  * @list: switch info entries to populate | 
 | 802 |  * | 
 | 803 |  * This command uses the old Exectute SNS Command mailbox routine. | 
 | 804 |  * | 
 | 805 |  * NOTE: Non-Nx_Ports are not requested. | 
 | 806 |  * | 
 | 807 |  * Returns 0 on success. | 
 | 808 |  */ | 
 | 809 | static int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 810 | qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 811 | { | 
 | 812 | 	int		rval; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 813 | 	struct qla_hw_data *ha = vha->hw; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 814 | 	uint16_t	i; | 
 | 815 | 	uint8_t		*entry; | 
 | 816 | 	struct sns_cmd_pkt	*sns_cmd; | 
 | 817 |  | 
 | 818 | 	/* Issue GID_PT. */ | 
 | 819 | 	/* Prepare SNS command request. */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 820 | 	sns_cmd = qla2x00_prep_sns_cmd(vha, GID_PT_CMD, GID_PT_SNS_SCMD_LEN, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 821 | 	    GID_PT_SNS_DATA_SIZE); | 
 | 822 |  | 
 | 823 | 	/* Prepare SNS command arguments -- port_type. */ | 
 | 824 | 	sns_cmd->p.cmd.param[0] = NS_NX_PORT_TYPE; | 
 | 825 |  | 
 | 826 | 	/* Execute SNS command. */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 827 | 	rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GID_PT_SNS_CMD_SIZE / 2, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 828 | 	    sizeof(struct sns_cmd_pkt)); | 
 | 829 | 	if (rval != QLA_SUCCESS) { | 
 | 830 | 		/*EMPTY*/ | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 831 | 		ql_dbg(ql_dbg_disc, vha, 0x206d, | 
 | 832 | 		    "GID_PT Send SNS failed (%d).\n", rval); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 833 | 	} else if (sns_cmd->p.gid_data[8] != 0x80 || | 
 | 834 | 	    sns_cmd->p.gid_data[9] != 0x02) { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 835 | 		ql_dbg(ql_dbg_disc, vha, 0x202f, | 
 | 836 | 		    "GID_PT failed, rejected request, gid_rsp:\n"); | 
 | 837 | 		ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2081, | 
 | 838 | 		    sns_cmd->p.gid_data, 16); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 839 | 		rval = QLA_FUNCTION_FAILED; | 
 | 840 | 	} else { | 
 | 841 | 		/* Set port IDs in switch info list. */ | 
 | 842 | 		for (i = 0; i < MAX_FIBRE_DEVICES; i++) { | 
 | 843 | 			entry = &sns_cmd->p.gid_data[(i * 4) + 16]; | 
 | 844 | 			list[i].d_id.b.domain = entry[1]; | 
 | 845 | 			list[i].d_id.b.area = entry[2]; | 
 | 846 | 			list[i].d_id.b.al_pa = entry[3]; | 
 | 847 |  | 
 | 848 | 			/* Last one exit. */ | 
 | 849 | 			if (entry[0] & BIT_7) { | 
 | 850 | 				list[i].d_id.b.rsvd_1 = entry[0]; | 
 | 851 | 				break; | 
 | 852 | 			} | 
 | 853 | 		} | 
 | 854 |  | 
 | 855 | 		/* | 
 | 856 | 		 * If we've used all available slots, then the switch is | 
 | 857 | 		 * reporting back more devices that we can handle with this | 
 | 858 | 		 * single call.  Return a failed status, and let GA_NXT handle | 
 | 859 | 		 * the overload. | 
 | 860 | 		 */ | 
| Andrew Vasquez | fa2a1ce | 2005-07-06 10:32:07 -0700 | [diff] [blame] | 861 | 		if (i == MAX_FIBRE_DEVICES) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 862 | 			rval = QLA_FUNCTION_FAILED; | 
 | 863 | 	} | 
 | 864 |  | 
 | 865 | 	return (rval); | 
 | 866 | } | 
 | 867 |  | 
 | 868 | /** | 
 | 869 |  * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query. | 
 | 870 |  * @ha: HA context | 
 | 871 |  * @list: switch info entries to populate | 
 | 872 |  * | 
 | 873 |  * This command uses the old Exectute SNS Command mailbox routine. | 
 | 874 |  * | 
 | 875 |  * Returns 0 on success. | 
 | 876 |  */ | 
 | 877 | static int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 878 | qla2x00_sns_gpn_id(scsi_qla_host_t *vha, sw_info_t *list) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 879 | { | 
 | 880 | 	int		rval; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 881 | 	struct qla_hw_data *ha = vha->hw; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 882 | 	uint16_t	i; | 
 | 883 | 	struct sns_cmd_pkt	*sns_cmd; | 
 | 884 |  | 
 | 885 | 	for (i = 0; i < MAX_FIBRE_DEVICES; i++) { | 
 | 886 | 		/* Issue GPN_ID */ | 
 | 887 | 		/* Prepare SNS command request. */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 888 | 		sns_cmd = qla2x00_prep_sns_cmd(vha, GPN_ID_CMD, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 889 | 		    GPN_ID_SNS_SCMD_LEN, GPN_ID_SNS_DATA_SIZE); | 
 | 890 |  | 
 | 891 | 		/* Prepare SNS command arguments -- port_id. */ | 
 | 892 | 		sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa; | 
 | 893 | 		sns_cmd->p.cmd.param[1] = list[i].d_id.b.area; | 
 | 894 | 		sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain; | 
 | 895 |  | 
 | 896 | 		/* Execute SNS command. */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 897 | 		rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 898 | 		    GPN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt)); | 
 | 899 | 		if (rval != QLA_SUCCESS) { | 
 | 900 | 			/*EMPTY*/ | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 901 | 			ql_dbg(ql_dbg_disc, vha, 0x2032, | 
 | 902 | 			    "GPN_ID Send SNS failed (%d).\n", rval); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 903 | 		} else if (sns_cmd->p.gpn_data[8] != 0x80 || | 
 | 904 | 		    sns_cmd->p.gpn_data[9] != 0x02) { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 905 | 			ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207e, | 
 | 906 | 			    "GPN_ID failed, rejected request, gpn_rsp:\n"); | 
 | 907 | 			ql_dump_buffer(ql_dbg_disc, vha, 0x207f, | 
 | 908 | 			    sns_cmd->p.gpn_data, 16); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 909 | 			rval = QLA_FUNCTION_FAILED; | 
 | 910 | 		} else { | 
 | 911 | 			/* Save portname */ | 
 | 912 | 			memcpy(list[i].port_name, &sns_cmd->p.gpn_data[16], | 
 | 913 | 			    WWN_SIZE); | 
 | 914 | 		} | 
 | 915 |  | 
 | 916 | 		/* Last device exit. */ | 
 | 917 | 		if (list[i].d_id.b.rsvd_1 != 0) | 
 | 918 | 			break; | 
 | 919 | 	} | 
 | 920 |  | 
 | 921 | 	return (rval); | 
 | 922 | } | 
 | 923 |  | 
 | 924 | /** | 
 | 925 |  * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query. | 
 | 926 |  * @ha: HA context | 
 | 927 |  * @list: switch info entries to populate | 
 | 928 |  * | 
 | 929 |  * This command uses the old Exectute SNS Command mailbox routine. | 
 | 930 |  * | 
 | 931 |  * Returns 0 on success. | 
 | 932 |  */ | 
 | 933 | static int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 934 | qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 935 | { | 
 | 936 | 	int		rval; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 937 | 	struct qla_hw_data *ha = vha->hw; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 938 | 	uint16_t	i; | 
 | 939 | 	struct sns_cmd_pkt	*sns_cmd; | 
 | 940 |  | 
 | 941 | 	for (i = 0; i < MAX_FIBRE_DEVICES; i++) { | 
 | 942 | 		/* Issue GNN_ID */ | 
 | 943 | 		/* Prepare SNS command request. */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 944 | 		sns_cmd = qla2x00_prep_sns_cmd(vha, GNN_ID_CMD, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 945 | 		    GNN_ID_SNS_SCMD_LEN, GNN_ID_SNS_DATA_SIZE); | 
 | 946 |  | 
 | 947 | 		/* Prepare SNS command arguments -- port_id. */ | 
 | 948 | 		sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa; | 
 | 949 | 		sns_cmd->p.cmd.param[1] = list[i].d_id.b.area; | 
 | 950 | 		sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain; | 
 | 951 |  | 
 | 952 | 		/* Execute SNS command. */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 953 | 		rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 954 | 		    GNN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt)); | 
 | 955 | 		if (rval != QLA_SUCCESS) { | 
 | 956 | 			/*EMPTY*/ | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 957 | 			ql_dbg(ql_dbg_disc, vha, 0x203f, | 
 | 958 | 			    "GNN_ID Send SNS failed (%d).\n", rval); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 959 | 		} else if (sns_cmd->p.gnn_data[8] != 0x80 || | 
 | 960 | 		    sns_cmd->p.gnn_data[9] != 0x02) { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 961 | 			ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2082, | 
 | 962 | 			    "GNN_ID failed, rejected request, gnn_rsp:\n"); | 
 | 963 | 			ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207a, | 
 | 964 | 			    sns_cmd->p.gnn_data, 16); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 965 | 			rval = QLA_FUNCTION_FAILED; | 
 | 966 | 		} else { | 
 | 967 | 			/* Save nodename */ | 
 | 968 | 			memcpy(list[i].node_name, &sns_cmd->p.gnn_data[16], | 
 | 969 | 			    WWN_SIZE); | 
 | 970 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 971 | 			ql_dbg(ql_dbg_disc, vha, 0x206e, | 
 | 972 | 			    "GID_PT entry - nn %02x%02x%02x%02x%02x%02x%02x%02x " | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 973 | 			    "pn %02x%02x%02x%02x%02x%02x%02x%02x " | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 974 | 			    "port_id=%02x%02x%02x.\n", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 975 | 			    list[i].node_name[0], list[i].node_name[1], | 
 | 976 | 			    list[i].node_name[2], list[i].node_name[3], | 
 | 977 | 			    list[i].node_name[4], list[i].node_name[5], | 
 | 978 | 			    list[i].node_name[6], list[i].node_name[7], | 
 | 979 | 			    list[i].port_name[0], list[i].port_name[1], | 
 | 980 | 			    list[i].port_name[2], list[i].port_name[3], | 
 | 981 | 			    list[i].port_name[4], list[i].port_name[5], | 
 | 982 | 			    list[i].port_name[6], list[i].port_name[7], | 
 | 983 | 			    list[i].d_id.b.domain, list[i].d_id.b.area, | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 984 | 			    list[i].d_id.b.al_pa); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 985 | 		} | 
 | 986 |  | 
 | 987 | 		/* Last device exit. */ | 
 | 988 | 		if (list[i].d_id.b.rsvd_1 != 0) | 
 | 989 | 			break; | 
 | 990 | 	} | 
 | 991 |  | 
 | 992 | 	return (rval); | 
 | 993 | } | 
 | 994 |  | 
 | 995 | /** | 
 | 996 |  * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. | 
 | 997 |  * @ha: HA context | 
 | 998 |  * | 
 | 999 |  * This command uses the old Exectute SNS Command mailbox routine. | 
 | 1000 |  * | 
 | 1001 |  * Returns 0 on success. | 
 | 1002 |  */ | 
 | 1003 | static int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1004 | qla2x00_sns_rft_id(scsi_qla_host_t *vha) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1005 | { | 
 | 1006 | 	int		rval; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1007 | 	struct qla_hw_data *ha = vha->hw; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1008 | 	struct sns_cmd_pkt	*sns_cmd; | 
 | 1009 |  | 
 | 1010 | 	/* Issue RFT_ID. */ | 
 | 1011 | 	/* Prepare SNS command request. */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1012 | 	sns_cmd = qla2x00_prep_sns_cmd(vha, RFT_ID_CMD, RFT_ID_SNS_SCMD_LEN, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1013 | 	    RFT_ID_SNS_DATA_SIZE); | 
 | 1014 |  | 
 | 1015 | 	/* Prepare SNS command arguments -- port_id, FC-4 types */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1016 | 	sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa; | 
 | 1017 | 	sns_cmd->p.cmd.param[1] = vha->d_id.b.area; | 
 | 1018 | 	sns_cmd->p.cmd.param[2] = vha->d_id.b.domain; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1019 |  | 
 | 1020 | 	sns_cmd->p.cmd.param[5] = 0x01;			/* FCP-3 */ | 
 | 1021 |  | 
 | 1022 | 	/* Execute SNS command. */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1023 | 	rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RFT_ID_SNS_CMD_SIZE / 2, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1024 | 	    sizeof(struct sns_cmd_pkt)); | 
 | 1025 | 	if (rval != QLA_SUCCESS) { | 
 | 1026 | 		/*EMPTY*/ | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1027 | 		ql_dbg(ql_dbg_disc, vha, 0x2060, | 
 | 1028 | 		    "RFT_ID Send SNS failed (%d).\n", rval); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1029 | 	} else if (sns_cmd->p.rft_data[8] != 0x80 || | 
 | 1030 | 	    sns_cmd->p.rft_data[9] != 0x02) { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1031 | 		ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2083, | 
 | 1032 | 		    "RFT_ID failed, rejected request rft_rsp:\n"); | 
 | 1033 | 		ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2080, | 
 | 1034 | 		    sns_cmd->p.rft_data, 16); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1035 | 		rval = QLA_FUNCTION_FAILED; | 
 | 1036 | 	} else { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1037 | 		ql_dbg(ql_dbg_disc, vha, 0x2073, | 
 | 1038 | 		    "RFT_ID exiting normally.\n"); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1039 | 	} | 
 | 1040 |  | 
 | 1041 | 	return (rval); | 
 | 1042 | } | 
 | 1043 |  | 
 | 1044 | /** | 
 | 1045 |  * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA. | 
 | 1046 |  * HBA. | 
 | 1047 |  * @ha: HA context | 
 | 1048 |  * | 
 | 1049 |  * This command uses the old Exectute SNS Command mailbox routine. | 
 | 1050 |  * | 
 | 1051 |  * Returns 0 on success. | 
 | 1052 |  */ | 
 | 1053 | static int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1054 | qla2x00_sns_rnn_id(scsi_qla_host_t *vha) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1055 | { | 
 | 1056 | 	int		rval; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1057 | 	struct qla_hw_data *ha = vha->hw; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1058 | 	struct sns_cmd_pkt	*sns_cmd; | 
 | 1059 |  | 
 | 1060 | 	/* Issue RNN_ID. */ | 
 | 1061 | 	/* Prepare SNS command request. */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1062 | 	sns_cmd = qla2x00_prep_sns_cmd(vha, RNN_ID_CMD, RNN_ID_SNS_SCMD_LEN, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1063 | 	    RNN_ID_SNS_DATA_SIZE); | 
 | 1064 |  | 
 | 1065 | 	/* Prepare SNS command arguments -- port_id, nodename. */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1066 | 	sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa; | 
 | 1067 | 	sns_cmd->p.cmd.param[1] = vha->d_id.b.area; | 
 | 1068 | 	sns_cmd->p.cmd.param[2] = vha->d_id.b.domain; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1069 |  | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1070 | 	sns_cmd->p.cmd.param[4] = vha->node_name[7]; | 
 | 1071 | 	sns_cmd->p.cmd.param[5] = vha->node_name[6]; | 
 | 1072 | 	sns_cmd->p.cmd.param[6] = vha->node_name[5]; | 
 | 1073 | 	sns_cmd->p.cmd.param[7] = vha->node_name[4]; | 
 | 1074 | 	sns_cmd->p.cmd.param[8] = vha->node_name[3]; | 
 | 1075 | 	sns_cmd->p.cmd.param[9] = vha->node_name[2]; | 
 | 1076 | 	sns_cmd->p.cmd.param[10] = vha->node_name[1]; | 
 | 1077 | 	sns_cmd->p.cmd.param[11] = vha->node_name[0]; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1078 |  | 
 | 1079 | 	/* Execute SNS command. */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1080 | 	rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RNN_ID_SNS_CMD_SIZE / 2, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1081 | 	    sizeof(struct sns_cmd_pkt)); | 
 | 1082 | 	if (rval != QLA_SUCCESS) { | 
 | 1083 | 		/*EMPTY*/ | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1084 | 		ql_dbg(ql_dbg_disc, vha, 0x204a, | 
 | 1085 | 		    "RNN_ID Send SNS failed (%d).\n", rval); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1086 | 	} else if (sns_cmd->p.rnn_data[8] != 0x80 || | 
 | 1087 | 	    sns_cmd->p.rnn_data[9] != 0x02) { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1088 | 		ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207b, | 
 | 1089 | 		    "RNN_ID failed, rejected request, rnn_rsp:\n"); | 
 | 1090 | 		ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207c, | 
 | 1091 | 		    sns_cmd->p.rnn_data, 16); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1092 | 		rval = QLA_FUNCTION_FAILED; | 
 | 1093 | 	} else { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1094 | 		ql_dbg(ql_dbg_disc, vha, 0x204c, | 
 | 1095 | 		    "RNN_ID exiting normally.\n"); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1096 | 	} | 
 | 1097 |  | 
 | 1098 | 	return (rval); | 
 | 1099 | } | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1100 |  | 
 | 1101 | /** | 
| Joe Perches | b1c1181 | 2008-02-03 17:28:22 +0200 | [diff] [blame] | 1102 |  * qla2x00_mgmt_svr_login() - Login to fabric Management Service. | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1103 |  * @ha: HA context | 
 | 1104 |  * | 
 | 1105 |  * Returns 0 on success. | 
 | 1106 |  */ | 
 | 1107 | static int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1108 | qla2x00_mgmt_svr_login(scsi_qla_host_t *vha) | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1109 | { | 
 | 1110 | 	int ret; | 
 | 1111 | 	uint16_t mb[MAILBOX_REGISTER_COUNT]; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1112 | 	struct qla_hw_data *ha = vha->hw; | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1113 | 	ret = QLA_SUCCESS; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1114 | 	if (vha->flags.management_server_logged_in) | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1115 | 		return ret; | 
 | 1116 |  | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1117 | 	ha->isp_ops->fabric_login(vha, vha->mgmt_svr_loop_id, 0xff, 0xff, 0xfa, | 
| Joe Carnuccio | e1f9160 | 2009-04-06 22:33:46 -0700 | [diff] [blame] | 1118 | 	    mb, BIT_1|BIT_0); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1119 | 	if (mb[0] != MBS_COMMAND_COMPLETE) { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1120 | 		ql_dbg(ql_dbg_disc, vha, 0x2024, | 
 | 1121 | 		    "Failed management_server login: loopid=%x mb[0]=%x " | 
 | 1122 | 		    "mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x.\n", | 
 | 1123 | 		    vha->mgmt_svr_loop_id, mb[0], mb[1], mb[2], mb[6], mb[7]); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1124 | 		ret = QLA_FUNCTION_FAILED; | 
 | 1125 | 	} else | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1126 | 		vha->flags.management_server_logged_in = 1; | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1127 |  | 
 | 1128 | 	return ret; | 
 | 1129 | } | 
 | 1130 |  | 
 | 1131 | /** | 
 | 1132 |  * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query. | 
 | 1133 |  * @ha: HA context | 
 | 1134 |  * @req_size: request size in bytes | 
 | 1135 |  * @rsp_size: response size in bytes | 
 | 1136 |  * | 
 | 1137 |  * Returns a pointer to the @ha's ms_iocb. | 
 | 1138 |  */ | 
 | 1139 | void * | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1140 | qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size, | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1141 |     uint32_t rsp_size) | 
 | 1142 | { | 
 | 1143 | 	ms_iocb_entry_t *ms_pkt; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1144 | 	struct qla_hw_data *ha = vha->hw; | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1145 | 	ms_pkt = ha->ms_iocb; | 
 | 1146 | 	memset(ms_pkt, 0, sizeof(ms_iocb_entry_t)); | 
 | 1147 |  | 
 | 1148 | 	ms_pkt->entry_type = MS_IOCB_TYPE; | 
 | 1149 | 	ms_pkt->entry_count = 1; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1150 | 	SET_TARGET_ID(ha, ms_pkt->loop_id, vha->mgmt_svr_loop_id); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1151 | 	ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG); | 
| Andrew Vasquez | 00a537b | 2008-02-28 14:06:11 -0800 | [diff] [blame] | 1152 | 	ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1153 | 	ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); | 
 | 1154 | 	ms_pkt->total_dsd_count = __constant_cpu_to_le16(2); | 
 | 1155 | 	ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size); | 
 | 1156 | 	ms_pkt->req_bytecount = cpu_to_le32(req_size); | 
 | 1157 |  | 
 | 1158 | 	ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); | 
 | 1159 | 	ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); | 
 | 1160 | 	ms_pkt->dseg_req_length = ms_pkt->req_bytecount; | 
 | 1161 |  | 
 | 1162 | 	ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); | 
 | 1163 | 	ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); | 
 | 1164 | 	ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount; | 
 | 1165 |  | 
 | 1166 | 	return ms_pkt; | 
 | 1167 | } | 
 | 1168 |  | 
 | 1169 | /** | 
 | 1170 |  * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query. | 
 | 1171 |  * @ha: HA context | 
 | 1172 |  * @req_size: request size in bytes | 
 | 1173 |  * @rsp_size: response size in bytes | 
 | 1174 |  * | 
 | 1175 |  * Returns a pointer to the @ha's ms_iocb. | 
 | 1176 |  */ | 
 | 1177 | void * | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1178 | qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size, | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1179 |     uint32_t rsp_size) | 
 | 1180 | { | 
 | 1181 | 	struct ct_entry_24xx *ct_pkt; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1182 | 	struct qla_hw_data *ha = vha->hw; | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1183 |  | 
 | 1184 | 	ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; | 
 | 1185 | 	memset(ct_pkt, 0, sizeof(struct ct_entry_24xx)); | 
 | 1186 |  | 
 | 1187 | 	ct_pkt->entry_type = CT_IOCB_TYPE; | 
 | 1188 | 	ct_pkt->entry_count = 1; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1189 | 	ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id); | 
| Andrew Vasquez | 00a537b | 2008-02-28 14:06:11 -0800 | [diff] [blame] | 1190 | 	ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1191 | 	ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); | 
 | 1192 | 	ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1); | 
 | 1193 | 	ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); | 
 | 1194 | 	ct_pkt->cmd_byte_count = cpu_to_le32(req_size); | 
 | 1195 |  | 
 | 1196 | 	ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); | 
 | 1197 | 	ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); | 
 | 1198 | 	ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; | 
 | 1199 |  | 
 | 1200 | 	ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); | 
 | 1201 | 	ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); | 
 | 1202 | 	ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1203 | 	ct_pkt->vp_index = vha->vp_idx; | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1204 |  | 
 | 1205 | 	return ct_pkt; | 
 | 1206 | } | 
 | 1207 |  | 
 | 1208 | static inline ms_iocb_entry_t * | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1209 | qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size) | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1210 | { | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1211 | 	struct qla_hw_data *ha = vha->hw; | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1212 | 	ms_iocb_entry_t *ms_pkt = ha->ms_iocb; | 
 | 1213 | 	struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; | 
 | 1214 |  | 
| Andrew Vasquez | e428924 | 2007-07-19 15:05:56 -0700 | [diff] [blame] | 1215 | 	if (IS_FWI2_CAPABLE(ha)) { | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1216 | 		ct_pkt->cmd_byte_count = cpu_to_le32(req_size); | 
 | 1217 | 		ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; | 
 | 1218 | 	} else { | 
 | 1219 | 		ms_pkt->req_bytecount = cpu_to_le32(req_size); | 
 | 1220 | 		ms_pkt->dseg_req_length = ms_pkt->req_bytecount; | 
 | 1221 | 	} | 
 | 1222 |  | 
 | 1223 | 	return ms_pkt; | 
 | 1224 | } | 
 | 1225 |  | 
 | 1226 | /** | 
 | 1227 |  * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query. | 
 | 1228 |  * @ct_req: CT request buffer | 
 | 1229 |  * @cmd: GS command | 
 | 1230 |  * @rsp_size: response size in bytes | 
 | 1231 |  * | 
 | 1232 |  * Returns a pointer to the intitialized @ct_req. | 
 | 1233 |  */ | 
 | 1234 | static inline struct ct_sns_req * | 
 | 1235 | qla2x00_prep_ct_fdmi_req(struct ct_sns_req *ct_req, uint16_t cmd, | 
 | 1236 |     uint16_t rsp_size) | 
 | 1237 | { | 
 | 1238 | 	memset(ct_req, 0, sizeof(struct ct_sns_pkt)); | 
 | 1239 |  | 
 | 1240 | 	ct_req->header.revision = 0x01; | 
 | 1241 | 	ct_req->header.gs_type = 0xFA; | 
 | 1242 | 	ct_req->header.gs_subtype = 0x10; | 
 | 1243 | 	ct_req->command = cpu_to_be16(cmd); | 
 | 1244 | 	ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); | 
 | 1245 |  | 
 | 1246 | 	return ct_req; | 
 | 1247 | } | 
 | 1248 |  | 
 | 1249 | /** | 
 | 1250 |  * qla2x00_fdmi_rhba() - | 
 | 1251 |  * @ha: HA context | 
 | 1252 |  * | 
 | 1253 |  * Returns 0 on success. | 
 | 1254 |  */ | 
 | 1255 | static int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1256 | qla2x00_fdmi_rhba(scsi_qla_host_t *vha) | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1257 | { | 
 | 1258 | 	int rval, alen; | 
 | 1259 | 	uint32_t size, sn; | 
 | 1260 |  | 
 | 1261 | 	ms_iocb_entry_t *ms_pkt; | 
 | 1262 | 	struct ct_sns_req *ct_req; | 
 | 1263 | 	struct ct_sns_rsp *ct_rsp; | 
 | 1264 | 	uint8_t *entries; | 
 | 1265 | 	struct ct_fdmi_hba_attr *eiter; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1266 | 	struct qla_hw_data *ha = vha->hw; | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1267 |  | 
 | 1268 | 	/* Issue RHBA */ | 
 | 1269 | 	/* Prepare common MS IOCB */ | 
 | 1270 | 	/*   Request size adjusted after CT preparation */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1271 | 	ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1272 |  | 
 | 1273 | 	/* Prepare CT request */ | 
 | 1274 | 	ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RHBA_CMD, | 
 | 1275 | 	    RHBA_RSP_SIZE); | 
 | 1276 | 	ct_rsp = &ha->ct_sns->p.rsp; | 
 | 1277 |  | 
 | 1278 | 	/* Prepare FDMI command arguments -- attribute block, attributes. */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1279 | 	memcpy(ct_req->req.rhba.hba_identifier, vha->port_name, WWN_SIZE); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1280 | 	ct_req->req.rhba.entry_count = __constant_cpu_to_be32(1); | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1281 | 	memcpy(ct_req->req.rhba.port_name, vha->port_name, WWN_SIZE); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1282 | 	size = 2 * WWN_SIZE + 4 + 4; | 
 | 1283 |  | 
 | 1284 | 	/* Attributes */ | 
 | 1285 | 	ct_req->req.rhba.attrs.count = | 
 | 1286 | 	    __constant_cpu_to_be32(FDMI_HBA_ATTR_COUNT); | 
 | 1287 | 	entries = ct_req->req.rhba.hba_identifier; | 
 | 1288 |  | 
 | 1289 | 	/* Nodename. */ | 
 | 1290 | 	eiter = (struct ct_fdmi_hba_attr *) (entries + size); | 
 | 1291 | 	eiter->type = __constant_cpu_to_be16(FDMI_HBA_NODE_NAME); | 
 | 1292 | 	eiter->len = __constant_cpu_to_be16(4 + WWN_SIZE); | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1293 | 	memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1294 | 	size += 4 + WWN_SIZE; | 
 | 1295 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1296 | 	ql_dbg(ql_dbg_disc, vha, 0x2025, | 
 | 1297 | 	    "NodeName = %02x%02x%02x%02x%02x%02x%02x%02x.\n", | 
 | 1298 | 	    eiter->a.node_name[0], eiter->a.node_name[1], | 
 | 1299 | 	    eiter->a.node_name[2], eiter->a.node_name[3], | 
 | 1300 | 	    eiter->a.node_name[4], eiter->a.node_name[5], | 
 | 1301 | 	    eiter->a.node_name[6], eiter->a.node_name[7]); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1302 |  | 
 | 1303 | 	/* Manufacturer. */ | 
 | 1304 | 	eiter = (struct ct_fdmi_hba_attr *) (entries + size); | 
 | 1305 | 	eiter->type = __constant_cpu_to_be16(FDMI_HBA_MANUFACTURER); | 
 | 1306 | 	strcpy(eiter->a.manufacturer, "QLogic Corporation"); | 
 | 1307 | 	alen = strlen(eiter->a.manufacturer); | 
 | 1308 | 	alen += (alen & 3) ? (4 - (alen & 3)) : 4; | 
 | 1309 | 	eiter->len = cpu_to_be16(4 + alen); | 
 | 1310 | 	size += 4 + alen; | 
 | 1311 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1312 | 	ql_dbg(ql_dbg_disc, vha, 0x2026, | 
 | 1313 | 	    "Manufacturer = %s.\n", eiter->a.manufacturer); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1314 |  | 
 | 1315 | 	/* Serial number. */ | 
 | 1316 | 	eiter = (struct ct_fdmi_hba_attr *) (entries + size); | 
 | 1317 | 	eiter->type = __constant_cpu_to_be16(FDMI_HBA_SERIAL_NUMBER); | 
 | 1318 | 	sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; | 
 | 1319 | 	sprintf(eiter->a.serial_num, "%c%05d", 'A' + sn / 100000, sn % 100000); | 
 | 1320 | 	alen = strlen(eiter->a.serial_num); | 
 | 1321 | 	alen += (alen & 3) ? (4 - (alen & 3)) : 4; | 
 | 1322 | 	eiter->len = cpu_to_be16(4 + alen); | 
 | 1323 | 	size += 4 + alen; | 
 | 1324 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1325 | 	ql_dbg(ql_dbg_disc, vha, 0x2027, | 
 | 1326 | 	    "Serial no. = %s.\n", eiter->a.serial_num); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1327 |  | 
 | 1328 | 	/* Model name. */ | 
 | 1329 | 	eiter = (struct ct_fdmi_hba_attr *) (entries + size); | 
 | 1330 | 	eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL); | 
 | 1331 | 	strcpy(eiter->a.model, ha->model_number); | 
 | 1332 | 	alen = strlen(eiter->a.model); | 
 | 1333 | 	alen += (alen & 3) ? (4 - (alen & 3)) : 4; | 
 | 1334 | 	eiter->len = cpu_to_be16(4 + alen); | 
 | 1335 | 	size += 4 + alen; | 
 | 1336 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1337 | 	ql_dbg(ql_dbg_disc, vha, 0x2028, | 
 | 1338 | 	    "Model Name = %s.\n", eiter->a.model); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1339 |  | 
 | 1340 | 	/* Model description. */ | 
 | 1341 | 	eiter = (struct ct_fdmi_hba_attr *) (entries + size); | 
 | 1342 | 	eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION); | 
 | 1343 | 	if (ha->model_desc) | 
 | 1344 | 		strncpy(eiter->a.model_desc, ha->model_desc, 80); | 
 | 1345 | 	alen = strlen(eiter->a.model_desc); | 
 | 1346 | 	alen += (alen & 3) ? (4 - (alen & 3)) : 4; | 
 | 1347 | 	eiter->len = cpu_to_be16(4 + alen); | 
 | 1348 | 	size += 4 + alen; | 
 | 1349 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1350 | 	ql_dbg(ql_dbg_disc, vha, 0x2029, | 
 | 1351 | 	    "Model Desc = %s.\n", eiter->a.model_desc); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1352 |  | 
 | 1353 | 	/* Hardware version. */ | 
 | 1354 | 	eiter = (struct ct_fdmi_hba_attr *) (entries + size); | 
 | 1355 | 	eiter->type = __constant_cpu_to_be16(FDMI_HBA_HARDWARE_VERSION); | 
 | 1356 | 	strcpy(eiter->a.hw_version, ha->adapter_id); | 
 | 1357 | 	alen = strlen(eiter->a.hw_version); | 
 | 1358 | 	alen += (alen & 3) ? (4 - (alen & 3)) : 4; | 
 | 1359 | 	eiter->len = cpu_to_be16(4 + alen); | 
 | 1360 | 	size += 4 + alen; | 
 | 1361 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1362 | 	ql_dbg(ql_dbg_disc, vha, 0x202a, | 
 | 1363 | 	    "Hardware ver = %s.\n", eiter->a.hw_version); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1364 |  | 
 | 1365 | 	/* Driver version. */ | 
 | 1366 | 	eiter = (struct ct_fdmi_hba_attr *) (entries + size); | 
 | 1367 | 	eiter->type = __constant_cpu_to_be16(FDMI_HBA_DRIVER_VERSION); | 
 | 1368 | 	strcpy(eiter->a.driver_version, qla2x00_version_str); | 
 | 1369 | 	alen = strlen(eiter->a.driver_version); | 
 | 1370 | 	alen += (alen & 3) ? (4 - (alen & 3)) : 4; | 
 | 1371 | 	eiter->len = cpu_to_be16(4 + alen); | 
 | 1372 | 	size += 4 + alen; | 
 | 1373 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1374 | 	ql_dbg(ql_dbg_disc, vha, 0x202b, | 
 | 1375 | 	    "Driver ver = %s.\n", eiter->a.driver_version); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1376 |  | 
 | 1377 | 	/* Option ROM version. */ | 
 | 1378 | 	eiter = (struct ct_fdmi_hba_attr *) (entries + size); | 
 | 1379 | 	eiter->type = __constant_cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION); | 
 | 1380 | 	strcpy(eiter->a.orom_version, "0.00"); | 
 | 1381 | 	alen = strlen(eiter->a.orom_version); | 
 | 1382 | 	alen += (alen & 3) ? (4 - (alen & 3)) : 4; | 
 | 1383 | 	eiter->len = cpu_to_be16(4 + alen); | 
 | 1384 | 	size += 4 + alen; | 
 | 1385 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1386 | 	ql_dbg(ql_dbg_disc, vha , 0x202c, | 
 | 1387 | 	    "Optrom vers = %s.\n", eiter->a.orom_version); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1388 |  | 
 | 1389 | 	/* Firmware version */ | 
 | 1390 | 	eiter = (struct ct_fdmi_hba_attr *) (entries + size); | 
 | 1391 | 	eiter->type = __constant_cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION); | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1392 | 	ha->isp_ops->fw_version_str(vha, eiter->a.fw_version); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1393 | 	alen = strlen(eiter->a.fw_version); | 
 | 1394 | 	alen += (alen & 3) ? (4 - (alen & 3)) : 4; | 
 | 1395 | 	eiter->len = cpu_to_be16(4 + alen); | 
 | 1396 | 	size += 4 + alen; | 
 | 1397 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1398 | 	ql_dbg(ql_dbg_disc, vha, 0x202d, | 
 | 1399 | 	    "Firmware vers = %s.\n", eiter->a.fw_version); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1400 |  | 
 | 1401 | 	/* Update MS request size. */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1402 | 	qla2x00_update_ms_fdmi_iocb(vha, size + 16); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1403 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1404 | 	ql_dbg(ql_dbg_disc, vha, 0x202e, | 
 | 1405 | 	    "RHBA identifier = " | 
 | 1406 | 	    "%02x%02x%02x%02x%02x%02x%02x%02x size=%d.\n", | 
 | 1407 | 	    ct_req->req.rhba.hba_identifier[0], | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1408 | 	    ct_req->req.rhba.hba_identifier[1], | 
 | 1409 | 	    ct_req->req.rhba.hba_identifier[2], | 
 | 1410 | 	    ct_req->req.rhba.hba_identifier[3], | 
 | 1411 | 	    ct_req->req.rhba.hba_identifier[4], | 
 | 1412 | 	    ct_req->req.rhba.hba_identifier[5], | 
 | 1413 | 	    ct_req->req.rhba.hba_identifier[6], | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1414 | 	    ct_req->req.rhba.hba_identifier[7], size); | 
 | 1415 | 	ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2076, | 
 | 1416 | 	    entries, size); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1417 |  | 
 | 1418 | 	/* Execute MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1419 | 	rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1420 | 	    sizeof(ms_iocb_entry_t)); | 
 | 1421 | 	if (rval != QLA_SUCCESS) { | 
 | 1422 | 		/*EMPTY*/ | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1423 | 		ql_dbg(ql_dbg_disc, vha, 0x2030, | 
 | 1424 | 		    "RHBA issue IOCB failed (%d).\n", rval); | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1425 | 	} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA") != | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1426 | 	    QLA_SUCCESS) { | 
 | 1427 | 		rval = QLA_FUNCTION_FAILED; | 
 | 1428 | 		if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM && | 
 | 1429 | 		    ct_rsp->header.explanation_code == | 
 | 1430 | 		    CT_EXPL_ALREADY_REGISTERED) { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1431 | 			ql_dbg(ql_dbg_disc, vha, 0x2034, | 
 | 1432 | 			    "HBA already registered.\n"); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1433 | 			rval = QLA_ALREADY_REGISTERED; | 
 | 1434 | 		} | 
 | 1435 | 	} else { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1436 | 		ql_dbg(ql_dbg_disc, vha, 0x2035, | 
 | 1437 | 		    "RHBA exiting normally.\n"); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1438 | 	} | 
 | 1439 |  | 
 | 1440 | 	return rval; | 
 | 1441 | } | 
 | 1442 |  | 
 | 1443 | /** | 
 | 1444 |  * qla2x00_fdmi_dhba() - | 
 | 1445 |  * @ha: HA context | 
 | 1446 |  * | 
 | 1447 |  * Returns 0 on success. | 
 | 1448 |  */ | 
 | 1449 | static int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1450 | qla2x00_fdmi_dhba(scsi_qla_host_t *vha) | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1451 | { | 
 | 1452 | 	int rval; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1453 | 	struct qla_hw_data *ha = vha->hw; | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1454 | 	ms_iocb_entry_t *ms_pkt; | 
 | 1455 | 	struct ct_sns_req *ct_req; | 
 | 1456 | 	struct ct_sns_rsp *ct_rsp; | 
 | 1457 |  | 
 | 1458 | 	/* Issue RPA */ | 
 | 1459 | 	/* Prepare common MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1460 | 	ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, DHBA_REQ_SIZE, | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1461 | 	    DHBA_RSP_SIZE); | 
 | 1462 |  | 
 | 1463 | 	/* Prepare CT request */ | 
 | 1464 | 	ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, DHBA_CMD, | 
 | 1465 | 	    DHBA_RSP_SIZE); | 
 | 1466 | 	ct_rsp = &ha->ct_sns->p.rsp; | 
 | 1467 |  | 
 | 1468 | 	/* Prepare FDMI command arguments -- portname. */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1469 | 	memcpy(ct_req->req.dhba.port_name, vha->port_name, WWN_SIZE); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1470 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1471 | 	ql_dbg(ql_dbg_disc, vha, 0x2036, | 
 | 1472 | 	    "DHBA portname = %02x%02x%02x%02x%02x%02x%02x%02x.\n", | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1473 | 	    ct_req->req.dhba.port_name[0], ct_req->req.dhba.port_name[1], | 
 | 1474 | 	    ct_req->req.dhba.port_name[2], ct_req->req.dhba.port_name[3], | 
 | 1475 | 	    ct_req->req.dhba.port_name[4], ct_req->req.dhba.port_name[5], | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1476 | 	    ct_req->req.dhba.port_name[6], ct_req->req.dhba.port_name[7]); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1477 |  | 
 | 1478 | 	/* Execute MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1479 | 	rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1480 | 	    sizeof(ms_iocb_entry_t)); | 
 | 1481 | 	if (rval != QLA_SUCCESS) { | 
 | 1482 | 		/*EMPTY*/ | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1483 | 		ql_dbg(ql_dbg_disc, vha, 0x2037, | 
 | 1484 | 		    "DHBA issue IOCB failed (%d).\n", rval); | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1485 | 	} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "DHBA") != | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1486 | 	    QLA_SUCCESS) { | 
 | 1487 | 		rval = QLA_FUNCTION_FAILED; | 
 | 1488 | 	} else { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1489 | 		ql_dbg(ql_dbg_disc, vha, 0x2038, | 
 | 1490 | 		    "DHBA exiting normally.\n"); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1491 | 	} | 
 | 1492 |  | 
 | 1493 | 	return rval; | 
 | 1494 | } | 
 | 1495 |  | 
 | 1496 | /** | 
 | 1497 |  * qla2x00_fdmi_rpa() - | 
 | 1498 |  * @ha: HA context | 
 | 1499 |  * | 
 | 1500 |  * Returns 0 on success. | 
 | 1501 |  */ | 
 | 1502 | static int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1503 | qla2x00_fdmi_rpa(scsi_qla_host_t *vha) | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1504 | { | 
 | 1505 | 	int rval, alen; | 
 | 1506 | 	uint32_t size, max_frame_size; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1507 | 	struct qla_hw_data *ha = vha->hw; | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1508 | 	ms_iocb_entry_t *ms_pkt; | 
 | 1509 | 	struct ct_sns_req *ct_req; | 
 | 1510 | 	struct ct_sns_rsp *ct_rsp; | 
 | 1511 | 	uint8_t *entries; | 
 | 1512 | 	struct ct_fdmi_port_attr *eiter; | 
 | 1513 | 	struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb; | 
 | 1514 |  | 
 | 1515 | 	/* Issue RPA */ | 
 | 1516 | 	/* Prepare common MS IOCB */ | 
 | 1517 | 	/*   Request size adjusted after CT preparation */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1518 | 	ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1519 |  | 
 | 1520 | 	/* Prepare CT request */ | 
 | 1521 | 	ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RPA_CMD, | 
 | 1522 | 	    RPA_RSP_SIZE); | 
 | 1523 | 	ct_rsp = &ha->ct_sns->p.rsp; | 
 | 1524 |  | 
 | 1525 | 	/* Prepare FDMI command arguments -- attribute block, attributes. */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1526 | 	memcpy(ct_req->req.rpa.port_name, vha->port_name, WWN_SIZE); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1527 | 	size = WWN_SIZE + 4; | 
 | 1528 |  | 
 | 1529 | 	/* Attributes */ | 
 | 1530 | 	ct_req->req.rpa.attrs.count = | 
| Andrew Vasquez | 8a85e17 | 2007-09-20 14:07:41 -0700 | [diff] [blame] | 1531 | 	    __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT - 1); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1532 | 	entries = ct_req->req.rpa.port_name; | 
 | 1533 |  | 
 | 1534 | 	/* FC4 types. */ | 
 | 1535 | 	eiter = (struct ct_fdmi_port_attr *) (entries + size); | 
 | 1536 | 	eiter->type = __constant_cpu_to_be16(FDMI_PORT_FC4_TYPES); | 
 | 1537 | 	eiter->len = __constant_cpu_to_be16(4 + 32); | 
 | 1538 | 	eiter->a.fc4_types[2] = 0x01; | 
 | 1539 | 	size += 4 + 32; | 
 | 1540 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1541 | 	ql_dbg(ql_dbg_disc, vha, 0x2039, | 
 | 1542 | 	    "FC4_TYPES=%02x %02x.\n", | 
 | 1543 | 	    eiter->a.fc4_types[2], | 
 | 1544 | 	    eiter->a.fc4_types[1]); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1545 |  | 
 | 1546 | 	/* Supported speed. */ | 
 | 1547 | 	eiter = (struct ct_fdmi_port_attr *) (entries + size); | 
 | 1548 | 	eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED); | 
 | 1549 | 	eiter->len = __constant_cpu_to_be16(4 + 4); | 
| Giridhar Malavali | a908301 | 2010-04-12 17:59:55 -0700 | [diff] [blame] | 1550 | 	if (IS_QLA8XXX_TYPE(ha)) | 
| Andrew Vasquez | 3a03eb7 | 2009-01-05 11:18:11 -0800 | [diff] [blame] | 1551 | 		eiter->a.sup_speed = __constant_cpu_to_be32( | 
 | 1552 | 		    FDMI_PORT_SPEED_10GB); | 
 | 1553 | 	else if (IS_QLA25XX(ha)) | 
| Andrew Vasquez | c3a2f0d | 2007-07-19 20:37:34 -0700 | [diff] [blame] | 1554 | 		eiter->a.sup_speed = __constant_cpu_to_be32( | 
 | 1555 | 		    FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| | 
 | 1556 | 		    FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_8GB); | 
| Harihara Kadayam | 4d4df19 | 2008-04-03 13:13:26 -0700 | [diff] [blame] | 1557 | 	else if (IS_QLA24XX_TYPE(ha)) | 
| Andrew Vasquez | 5881569 | 2007-07-19 15:05:58 -0700 | [diff] [blame] | 1558 | 		eiter->a.sup_speed = __constant_cpu_to_be32( | 
 | 1559 | 		    FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| | 
 | 1560 | 		    FDMI_PORT_SPEED_4GB); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1561 | 	else if (IS_QLA23XX(ha)) | 
| Andrew Vasquez | 5881569 | 2007-07-19 15:05:58 -0700 | [diff] [blame] | 1562 | 		eiter->a.sup_speed =__constant_cpu_to_be32( | 
 | 1563 | 		    FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1564 | 	else | 
| Andrew Vasquez | 5881569 | 2007-07-19 15:05:58 -0700 | [diff] [blame] | 1565 | 		eiter->a.sup_speed = __constant_cpu_to_be32( | 
 | 1566 | 		    FDMI_PORT_SPEED_1GB); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1567 | 	size += 4 + 4; | 
 | 1568 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1569 | 	ql_dbg(ql_dbg_disc, vha, 0x203a, | 
 | 1570 | 	    "Supported_Speed=%x.\n", eiter->a.sup_speed); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1571 |  | 
 | 1572 | 	/* Current speed. */ | 
 | 1573 | 	eiter = (struct ct_fdmi_port_attr *) (entries + size); | 
 | 1574 | 	eiter->type = __constant_cpu_to_be16(FDMI_PORT_CURRENT_SPEED); | 
 | 1575 | 	eiter->len = __constant_cpu_to_be16(4 + 4); | 
 | 1576 | 	switch (ha->link_data_rate) { | 
| Andrew Vasquez | 5881569 | 2007-07-19 15:05:58 -0700 | [diff] [blame] | 1577 | 	case PORT_SPEED_1GB: | 
 | 1578 | 		eiter->a.cur_speed = | 
 | 1579 | 		    __constant_cpu_to_be32(FDMI_PORT_SPEED_1GB); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1580 | 		break; | 
| Andrew Vasquez | 5881569 | 2007-07-19 15:05:58 -0700 | [diff] [blame] | 1581 | 	case PORT_SPEED_2GB: | 
 | 1582 | 		eiter->a.cur_speed = | 
 | 1583 | 		    __constant_cpu_to_be32(FDMI_PORT_SPEED_2GB); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1584 | 		break; | 
| Andrew Vasquez | 5881569 | 2007-07-19 15:05:58 -0700 | [diff] [blame] | 1585 | 	case PORT_SPEED_4GB: | 
 | 1586 | 		eiter->a.cur_speed = | 
 | 1587 | 		    __constant_cpu_to_be32(FDMI_PORT_SPEED_4GB); | 
 | 1588 | 		break; | 
| Andrew Vasquez | c3a2f0d | 2007-07-19 20:37:34 -0700 | [diff] [blame] | 1589 | 	case PORT_SPEED_8GB: | 
 | 1590 | 		eiter->a.cur_speed = | 
 | 1591 | 		    __constant_cpu_to_be32(FDMI_PORT_SPEED_8GB); | 
 | 1592 | 		break; | 
| Andrew Vasquez | 3a03eb7 | 2009-01-05 11:18:11 -0800 | [diff] [blame] | 1593 | 	case PORT_SPEED_10GB: | 
 | 1594 | 		eiter->a.cur_speed = | 
 | 1595 | 		    __constant_cpu_to_be32(FDMI_PORT_SPEED_10GB); | 
 | 1596 | 		break; | 
| Andrew Vasquez | 5881569 | 2007-07-19 15:05:58 -0700 | [diff] [blame] | 1597 | 	default: | 
 | 1598 | 		eiter->a.cur_speed = | 
 | 1599 | 		    __constant_cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1600 | 		break; | 
 | 1601 | 	} | 
 | 1602 | 	size += 4 + 4; | 
 | 1603 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1604 | 	ql_dbg(ql_dbg_disc, vha, 0x203b, | 
 | 1605 | 	    "Current_Speed=%x.\n", eiter->a.cur_speed); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1606 |  | 
 | 1607 | 	/* Max frame size. */ | 
 | 1608 | 	eiter = (struct ct_fdmi_port_attr *) (entries + size); | 
 | 1609 | 	eiter->type = __constant_cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE); | 
 | 1610 | 	eiter->len = __constant_cpu_to_be16(4 + 4); | 
| Andrew Vasquez | e428924 | 2007-07-19 15:05:56 -0700 | [diff] [blame] | 1611 | 	max_frame_size = IS_FWI2_CAPABLE(ha) ? | 
| Seokmann Ju | c6852c4 | 2008-04-24 15:21:29 -0700 | [diff] [blame] | 1612 | 	    le16_to_cpu(icb24->frame_payload_size): | 
 | 1613 | 	    le16_to_cpu(ha->init_cb->frame_payload_size); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1614 | 	eiter->a.max_frame_size = cpu_to_be32(max_frame_size); | 
 | 1615 | 	size += 4 + 4; | 
 | 1616 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1617 | 	ql_dbg(ql_dbg_disc, vha, 0x203c, | 
 | 1618 | 	    "Max_Frame_Size=%x.\n", eiter->a.max_frame_size); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1619 |  | 
 | 1620 | 	/* OS device name. */ | 
 | 1621 | 	eiter = (struct ct_fdmi_port_attr *) (entries + size); | 
 | 1622 | 	eiter->type = __constant_cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME); | 
| Andrew Vasquez | 8a85e17 | 2007-09-20 14:07:41 -0700 | [diff] [blame] | 1623 | 	strcpy(eiter->a.os_dev_name, QLA2XXX_DRIVER_NAME); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1624 | 	alen = strlen(eiter->a.os_dev_name); | 
 | 1625 | 	alen += (alen & 3) ? (4 - (alen & 3)) : 4; | 
 | 1626 | 	eiter->len = cpu_to_be16(4 + alen); | 
 | 1627 | 	size += 4 + alen; | 
 | 1628 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1629 | 	ql_dbg(ql_dbg_disc, vha, 0x204b, | 
 | 1630 | 	    "OS_Device_Name=%s.\n", eiter->a.os_dev_name); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1631 |  | 
| Andrew Vasquez | a740a3f | 2006-10-02 12:00:45 -0700 | [diff] [blame] | 1632 | 	/* Hostname. */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1633 | 	if (strlen(fc_host_system_hostname(vha->host))) { | 
| Andrew Vasquez | 8a85e17 | 2007-09-20 14:07:41 -0700 | [diff] [blame] | 1634 | 		ct_req->req.rpa.attrs.count = | 
 | 1635 | 		    __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT); | 
| Andrew Vasquez | a740a3f | 2006-10-02 12:00:45 -0700 | [diff] [blame] | 1636 | 		eiter = (struct ct_fdmi_port_attr *) (entries + size); | 
 | 1637 | 		eiter->type = __constant_cpu_to_be16(FDMI_PORT_HOST_NAME); | 
 | 1638 | 		snprintf(eiter->a.host_name, sizeof(eiter->a.host_name), | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1639 | 		    "%s", fc_host_system_hostname(vha->host)); | 
| Andrew Vasquez | a740a3f | 2006-10-02 12:00:45 -0700 | [diff] [blame] | 1640 | 		alen = strlen(eiter->a.host_name); | 
 | 1641 | 		alen += (alen & 3) ? (4 - (alen & 3)) : 4; | 
 | 1642 | 		eiter->len = cpu_to_be16(4 + alen); | 
 | 1643 | 		size += 4 + alen; | 
 | 1644 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1645 | 		ql_dbg(ql_dbg_disc, vha, 0x203d, | 
 | 1646 | 		    "HostName=%s.\n", eiter->a.host_name); | 
| Andrew Vasquez | a740a3f | 2006-10-02 12:00:45 -0700 | [diff] [blame] | 1647 | 	} | 
 | 1648 |  | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1649 | 	/* Update MS request size. */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1650 | 	qla2x00_update_ms_fdmi_iocb(vha, size + 16); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1651 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1652 | 	ql_dbg(ql_dbg_disc, vha, 0x203e, | 
 | 1653 | 	    "RPA portname= %02x%02x%02x%02x%02X%02x%02x%02x size=%d.\n", | 
 | 1654 | 	    ct_req->req.rpa.port_name[0], ct_req->req.rpa.port_name[1], | 
 | 1655 | 	    ct_req->req.rpa.port_name[2], ct_req->req.rpa.port_name[3], | 
 | 1656 | 	    ct_req->req.rpa.port_name[4], ct_req->req.rpa.port_name[5], | 
 | 1657 | 	    ct_req->req.rpa.port_name[6], ct_req->req.rpa.port_name[7], | 
 | 1658 | 	    size); | 
 | 1659 | 	ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2079, | 
 | 1660 | 	    entries, size); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1661 |  | 
 | 1662 | 	/* Execute MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1663 | 	rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1664 | 	    sizeof(ms_iocb_entry_t)); | 
 | 1665 | 	if (rval != QLA_SUCCESS) { | 
 | 1666 | 		/*EMPTY*/ | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1667 | 		ql_dbg(ql_dbg_disc, vha, 0x2040, | 
 | 1668 | 		    "RPA issue IOCB failed (%d).\n", rval); | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1669 | 	} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA") != | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1670 | 	    QLA_SUCCESS) { | 
 | 1671 | 		rval = QLA_FUNCTION_FAILED; | 
 | 1672 | 	} else { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1673 | 		ql_dbg(ql_dbg_disc, vha, 0x2041, | 
 | 1674 | 		    "RPA exiting nornally.\n"); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1675 | 	} | 
 | 1676 |  | 
 | 1677 | 	return rval; | 
 | 1678 | } | 
 | 1679 |  | 
 | 1680 | /** | 
 | 1681 |  * qla2x00_fdmi_register() - | 
 | 1682 |  * @ha: HA context | 
 | 1683 |  * | 
 | 1684 |  * Returns 0 on success. | 
 | 1685 |  */ | 
 | 1686 | int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1687 | qla2x00_fdmi_register(scsi_qla_host_t *vha) | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1688 | { | 
 | 1689 | 	int rval; | 
| Andrew Vasquez | 80de7ef | 2009-07-31 15:09:33 -0700 | [diff] [blame] | 1690 |        struct qla_hw_data *ha = vha->hw; | 
 | 1691 |  | 
 | 1692 | 	if (IS_QLA2100(ha) || IS_QLA2200(ha)) | 
 | 1693 | 		return QLA_FUNCTION_FAILED; | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1694 |  | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1695 | 	rval = qla2x00_mgmt_svr_login(vha); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1696 | 	if (rval) | 
 | 1697 | 		return rval; | 
 | 1698 |  | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1699 | 	rval = qla2x00_fdmi_rhba(vha); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1700 | 	if (rval) { | 
 | 1701 | 		if (rval != QLA_ALREADY_REGISTERED) | 
 | 1702 | 			return rval; | 
 | 1703 |  | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1704 | 		rval = qla2x00_fdmi_dhba(vha); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1705 | 		if (rval) | 
 | 1706 | 			return rval; | 
 | 1707 |  | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1708 | 		rval = qla2x00_fdmi_rhba(vha); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1709 | 		if (rval) | 
 | 1710 | 			return rval; | 
 | 1711 | 	} | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1712 | 	rval = qla2x00_fdmi_rpa(vha); | 
| Andrew Vasquez | cca5335 | 2005-08-26 19:08:30 -0700 | [diff] [blame] | 1713 |  | 
 | 1714 | 	return rval; | 
 | 1715 | } | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1716 |  | 
 | 1717 | /** | 
 | 1718 |  * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query. | 
 | 1719 |  * @ha: HA context | 
 | 1720 |  * @list: switch info entries to populate | 
 | 1721 |  * | 
 | 1722 |  * Returns 0 on success. | 
 | 1723 |  */ | 
 | 1724 | int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1725 | qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list) | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1726 | { | 
 | 1727 | 	int		rval; | 
 | 1728 | 	uint16_t	i; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1729 | 	struct qla_hw_data *ha = vha->hw; | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1730 | 	ms_iocb_entry_t	*ms_pkt; | 
 | 1731 | 	struct ct_sns_req	*ct_req; | 
 | 1732 | 	struct ct_sns_rsp	*ct_rsp; | 
 | 1733 |  | 
| Andrew Vasquez | c76f2c0 | 2007-07-19 15:05:57 -0700 | [diff] [blame] | 1734 | 	if (!IS_IIDMA_CAPABLE(ha)) | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1735 | 		return QLA_FUNCTION_FAILED; | 
 | 1736 |  | 
 | 1737 | 	for (i = 0; i < MAX_FIBRE_DEVICES; i++) { | 
 | 1738 | 		/* Issue GFPN_ID */ | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1739 | 		/* Prepare common MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1740 | 		ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GFPN_ID_REQ_SIZE, | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1741 | 		    GFPN_ID_RSP_SIZE); | 
 | 1742 |  | 
 | 1743 | 		/* Prepare CT request */ | 
 | 1744 | 		ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFPN_ID_CMD, | 
 | 1745 | 		    GFPN_ID_RSP_SIZE); | 
 | 1746 | 		ct_rsp = &ha->ct_sns->p.rsp; | 
 | 1747 |  | 
 | 1748 | 		/* Prepare CT arguments -- port_id */ | 
 | 1749 | 		ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; | 
 | 1750 | 		ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; | 
 | 1751 | 		ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; | 
 | 1752 |  | 
 | 1753 | 		/* Execute MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1754 | 		rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1755 | 		    sizeof(ms_iocb_entry_t)); | 
 | 1756 | 		if (rval != QLA_SUCCESS) { | 
 | 1757 | 			/*EMPTY*/ | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1758 | 			ql_dbg(ql_dbg_disc, vha, 0x2023, | 
 | 1759 | 			    "GFPN_ID issue IOCB failed (%d).\n", rval); | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1760 | 		} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1761 | 		    "GFPN_ID") != QLA_SUCCESS) { | 
 | 1762 | 			rval = QLA_FUNCTION_FAILED; | 
 | 1763 | 		} else { | 
 | 1764 | 			/* Save fabric portname */ | 
 | 1765 | 			memcpy(list[i].fabric_port_name, | 
 | 1766 | 			    ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE); | 
 | 1767 | 		} | 
 | 1768 |  | 
 | 1769 | 		/* Last device exit. */ | 
 | 1770 | 		if (list[i].d_id.b.rsvd_1 != 0) | 
 | 1771 | 			break; | 
 | 1772 | 	} | 
 | 1773 |  | 
 | 1774 | 	return (rval); | 
 | 1775 | } | 
 | 1776 |  | 
 | 1777 | static inline void * | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1778 | qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *vha, uint32_t req_size, | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1779 |     uint32_t rsp_size) | 
 | 1780 | { | 
 | 1781 | 	struct ct_entry_24xx *ct_pkt; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1782 | 	struct qla_hw_data *ha = vha->hw; | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1783 | 	ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; | 
 | 1784 | 	memset(ct_pkt, 0, sizeof(struct ct_entry_24xx)); | 
 | 1785 |  | 
 | 1786 | 	ct_pkt->entry_type = CT_IOCB_TYPE; | 
 | 1787 | 	ct_pkt->entry_count = 1; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1788 | 	ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id); | 
| Andrew Vasquez | 00a537b | 2008-02-28 14:06:11 -0800 | [diff] [blame] | 1789 | 	ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1790 | 	ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); | 
 | 1791 | 	ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1); | 
 | 1792 | 	ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); | 
 | 1793 | 	ct_pkt->cmd_byte_count = cpu_to_le32(req_size); | 
 | 1794 |  | 
 | 1795 | 	ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); | 
 | 1796 | 	ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); | 
 | 1797 | 	ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; | 
 | 1798 |  | 
 | 1799 | 	ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); | 
 | 1800 | 	ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); | 
 | 1801 | 	ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1802 | 	ct_pkt->vp_index = vha->vp_idx; | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1803 |  | 
 | 1804 | 	return ct_pkt; | 
 | 1805 | } | 
 | 1806 |  | 
 | 1807 |  | 
 | 1808 | static inline struct ct_sns_req * | 
 | 1809 | qla24xx_prep_ct_fm_req(struct ct_sns_req *ct_req, uint16_t cmd, | 
 | 1810 |     uint16_t rsp_size) | 
 | 1811 | { | 
 | 1812 | 	memset(ct_req, 0, sizeof(struct ct_sns_pkt)); | 
 | 1813 |  | 
 | 1814 | 	ct_req->header.revision = 0x01; | 
 | 1815 | 	ct_req->header.gs_type = 0xFA; | 
 | 1816 | 	ct_req->header.gs_subtype = 0x01; | 
 | 1817 | 	ct_req->command = cpu_to_be16(cmd); | 
 | 1818 | 	ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); | 
 | 1819 |  | 
 | 1820 | 	return ct_req; | 
 | 1821 | } | 
 | 1822 |  | 
 | 1823 | /** | 
 | 1824 |  * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query. | 
 | 1825 |  * @ha: HA context | 
 | 1826 |  * @list: switch info entries to populate | 
 | 1827 |  * | 
 | 1828 |  * Returns 0 on success. | 
 | 1829 |  */ | 
 | 1830 | int | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1831 | qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list) | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1832 | { | 
 | 1833 | 	int		rval; | 
 | 1834 | 	uint16_t	i; | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1835 | 	struct qla_hw_data *ha = vha->hw; | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1836 | 	ms_iocb_entry_t	*ms_pkt; | 
 | 1837 | 	struct ct_sns_req	*ct_req; | 
 | 1838 | 	struct ct_sns_rsp	*ct_rsp; | 
 | 1839 |  | 
| Andrew Vasquez | c76f2c0 | 2007-07-19 15:05:57 -0700 | [diff] [blame] | 1840 | 	if (!IS_IIDMA_CAPABLE(ha)) | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1841 | 		return QLA_FUNCTION_FAILED; | 
| Andrew Vasquez | 4346b14 | 2006-12-13 19:20:28 -0800 | [diff] [blame] | 1842 | 	if (!ha->flags.gpsc_supported) | 
 | 1843 | 		return QLA_FUNCTION_FAILED; | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1844 |  | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1845 | 	rval = qla2x00_mgmt_svr_login(vha); | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1846 | 	if (rval) | 
 | 1847 | 		return rval; | 
 | 1848 |  | 
 | 1849 | 	for (i = 0; i < MAX_FIBRE_DEVICES; i++) { | 
 | 1850 | 		/* Issue GFPN_ID */ | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1851 | 		/* Prepare common MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1852 | 		ms_pkt = qla24xx_prep_ms_fm_iocb(vha, GPSC_REQ_SIZE, | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1853 | 		    GPSC_RSP_SIZE); | 
 | 1854 |  | 
 | 1855 | 		/* Prepare CT request */ | 
 | 1856 | 		ct_req = qla24xx_prep_ct_fm_req(&ha->ct_sns->p.req, | 
 | 1857 | 		    GPSC_CMD, GPSC_RSP_SIZE); | 
 | 1858 | 		ct_rsp = &ha->ct_sns->p.rsp; | 
 | 1859 |  | 
 | 1860 | 		/* Prepare CT arguments -- port_name */ | 
 | 1861 | 		memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name, | 
 | 1862 | 		    WWN_SIZE); | 
 | 1863 |  | 
 | 1864 | 		/* Execute MS IOCB */ | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1865 | 		rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1866 | 		    sizeof(ms_iocb_entry_t)); | 
 | 1867 | 		if (rval != QLA_SUCCESS) { | 
 | 1868 | 			/*EMPTY*/ | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1869 | 			ql_dbg(ql_dbg_disc, vha, 0x2059, | 
 | 1870 | 			    "GPSC issue IOCB failed (%d).\n", rval); | 
| Anirban Chakraborty | 7b867cf | 2008-11-06 10:40:19 -0800 | [diff] [blame] | 1871 | 		} else if ((rval = qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, | 
| Andrew Vasquez | 4346b14 | 2006-12-13 19:20:28 -0800 | [diff] [blame] | 1872 | 		    "GPSC")) != QLA_SUCCESS) { | 
 | 1873 | 			/* FM command unsupported? */ | 
 | 1874 | 			if (rval == QLA_INVALID_COMMAND && | 
| Andrew Vasquez | 3fe7cfb | 2008-04-03 13:13:23 -0700 | [diff] [blame] | 1875 | 			    (ct_rsp->header.reason_code == | 
 | 1876 | 				CT_REASON_INVALID_COMMAND_CODE || | 
 | 1877 | 			     ct_rsp->header.reason_code == | 
 | 1878 | 				CT_REASON_COMMAND_UNSUPPORTED)) { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1879 | 				ql_dbg(ql_dbg_disc, vha, 0x205a, | 
 | 1880 | 				    "GPSC command unsupported, disabling " | 
 | 1881 | 				    "query.\n"); | 
| Andrew Vasquez | 4346b14 | 2006-12-13 19:20:28 -0800 | [diff] [blame] | 1882 | 				ha->flags.gpsc_supported = 0; | 
 | 1883 | 				rval = QLA_FUNCTION_FAILED; | 
 | 1884 | 				break; | 
 | 1885 | 			} | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1886 | 			rval = QLA_FUNCTION_FAILED; | 
 | 1887 | 		} else { | 
| Andrew Vasquez | a3cbdfa | 2007-08-13 10:13:18 -0700 | [diff] [blame] | 1888 | 			/* Save port-speed */ | 
 | 1889 | 			switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) { | 
 | 1890 | 			case BIT_15: | 
 | 1891 | 				list[i].fp_speed = PORT_SPEED_1GB; | 
 | 1892 | 				break; | 
 | 1893 | 			case BIT_14: | 
 | 1894 | 				list[i].fp_speed = PORT_SPEED_2GB; | 
 | 1895 | 				break; | 
 | 1896 | 			case BIT_13: | 
 | 1897 | 				list[i].fp_speed = PORT_SPEED_4GB; | 
 | 1898 | 				break; | 
| Andrew Vasquez | 9f8fdde | 2009-06-03 09:55:22 -0700 | [diff] [blame] | 1899 | 			case BIT_12: | 
 | 1900 | 				list[i].fp_speed = PORT_SPEED_10GB; | 
 | 1901 | 				break; | 
| Andrew Vasquez | a3cbdfa | 2007-08-13 10:13:18 -0700 | [diff] [blame] | 1902 | 			case BIT_11: | 
 | 1903 | 				list[i].fp_speed = PORT_SPEED_8GB; | 
 | 1904 | 				break; | 
 | 1905 | 			} | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1906 |  | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1907 | 			ql_dbg(ql_dbg_disc, vha, 0x205b, | 
 | 1908 | 			    "GPSC ext entry - fpn " | 
 | 1909 | 			    "%02x%02x%02x%02x%02x%02x%02x%02x speeds=%04x " | 
 | 1910 | 			    "speed=%04x.\n", | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1911 | 			    list[i].fabric_port_name[0], | 
 | 1912 | 			    list[i].fabric_port_name[1], | 
 | 1913 | 			    list[i].fabric_port_name[2], | 
 | 1914 | 			    list[i].fabric_port_name[3], | 
 | 1915 | 			    list[i].fabric_port_name[4], | 
 | 1916 | 			    list[i].fabric_port_name[5], | 
 | 1917 | 			    list[i].fabric_port_name[6], | 
 | 1918 | 			    list[i].fabric_port_name[7], | 
| Andrew Vasquez | a3cbdfa | 2007-08-13 10:13:18 -0700 | [diff] [blame] | 1919 | 			    be16_to_cpu(ct_rsp->rsp.gpsc.speeds), | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1920 | 			    be16_to_cpu(ct_rsp->rsp.gpsc.speed)); | 
| Andrew Vasquez | d8b4521 | 2006-10-02 12:00:43 -0700 | [diff] [blame] | 1921 | 		} | 
 | 1922 |  | 
 | 1923 | 		/* Last device exit. */ | 
 | 1924 | 		if (list[i].d_id.b.rsvd_1 != 0) | 
 | 1925 | 			break; | 
 | 1926 | 	} | 
 | 1927 |  | 
 | 1928 | 	return (rval); | 
 | 1929 | } | 
| Chad Dupuis | e8c72ba | 2010-07-23 15:28:25 +0500 | [diff] [blame] | 1930 |  | 
 | 1931 | /** | 
 | 1932 |  * qla2x00_gff_id() - SNS Get FC-4 Features (GFF_ID) query. | 
 | 1933 |  * | 
 | 1934 |  * @ha: HA context | 
 | 1935 |  * @list: switch info entries to populate | 
 | 1936 |  * | 
 | 1937 |  */ | 
 | 1938 | void | 
 | 1939 | qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list) | 
 | 1940 | { | 
 | 1941 | 	int		rval; | 
 | 1942 | 	uint16_t	i; | 
 | 1943 |  | 
 | 1944 | 	ms_iocb_entry_t	*ms_pkt; | 
 | 1945 | 	struct ct_sns_req	*ct_req; | 
 | 1946 | 	struct ct_sns_rsp	*ct_rsp; | 
 | 1947 | 	struct qla_hw_data *ha = vha->hw; | 
 | 1948 | 	uint8_t fcp_scsi_features = 0; | 
 | 1949 |  | 
 | 1950 | 	for (i = 0; i < MAX_FIBRE_DEVICES; i++) { | 
 | 1951 | 		/* Set default FC4 Type as UNKNOWN so the default is to | 
 | 1952 | 		 * Process this port */ | 
 | 1953 | 		list[i].fc4_type = FC4_TYPE_UNKNOWN; | 
 | 1954 |  | 
 | 1955 | 		/* Do not attempt GFF_ID if we are not FWI_2 capable */ | 
 | 1956 | 		if (!IS_FWI2_CAPABLE(ha)) | 
 | 1957 | 			continue; | 
 | 1958 |  | 
 | 1959 | 		/* Prepare common MS IOCB */ | 
 | 1960 | 		ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GFF_ID_REQ_SIZE, | 
 | 1961 | 		    GFF_ID_RSP_SIZE); | 
 | 1962 |  | 
 | 1963 | 		/* Prepare CT request */ | 
 | 1964 | 		ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFF_ID_CMD, | 
 | 1965 | 		    GFF_ID_RSP_SIZE); | 
 | 1966 | 		ct_rsp = &ha->ct_sns->p.rsp; | 
 | 1967 |  | 
 | 1968 | 		/* Prepare CT arguments -- port_id */ | 
 | 1969 | 		ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; | 
 | 1970 | 		ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; | 
 | 1971 | 		ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; | 
 | 1972 |  | 
 | 1973 | 		/* Execute MS IOCB */ | 
 | 1974 | 		rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, | 
 | 1975 | 		   sizeof(ms_iocb_entry_t)); | 
 | 1976 |  | 
 | 1977 | 		if (rval != QLA_SUCCESS) { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1978 | 			ql_dbg(ql_dbg_disc, vha, 0x205c, | 
 | 1979 | 			    "GFF_ID issue IOCB failed (%d).\n", rval); | 
| Chad Dupuis | e8c72ba | 2010-07-23 15:28:25 +0500 | [diff] [blame] | 1980 | 		} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, | 
| Andrew Vasquez | 7a78ced | 2011-02-23 15:27:12 -0800 | [diff] [blame] | 1981 | 			       "GFF_ID") != QLA_SUCCESS) { | 
| Saurav Kashyap | 7c3df13 | 2011-07-14 12:00:13 -0700 | [diff] [blame] | 1982 | 			ql_dbg(ql_dbg_disc, vha, 0x205d, | 
 | 1983 | 			    "GFF_ID IOCB status had a failure status code.\n"); | 
| Chad Dupuis | e8c72ba | 2010-07-23 15:28:25 +0500 | [diff] [blame] | 1984 | 		} else { | 
 | 1985 | 			fcp_scsi_features = | 
 | 1986 | 			   ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET]; | 
 | 1987 | 			fcp_scsi_features &= 0x0f; | 
 | 1988 |  | 
 | 1989 | 			if (fcp_scsi_features) | 
 | 1990 | 				list[i].fc4_type = FC4_TYPE_FCP_SCSI; | 
 | 1991 | 			else | 
 | 1992 | 				list[i].fc4_type = FC4_TYPE_OTHER; | 
 | 1993 | 		} | 
 | 1994 |  | 
 | 1995 | 		/* Last device exit. */ | 
 | 1996 | 		if (list[i].d_id.b.rsvd_1 != 0) | 
 | 1997 | 			break; | 
 | 1998 | 	} | 
 | 1999 | } |