diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_def.h | 40 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_fw.h | 45 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_init.c | 218 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_mbx.c | 284 |
4 files changed, 445 insertions, 142 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index 81b5f29254e2..3175709d4861 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h | |||
@@ -114,6 +114,7 @@ | |||
114 | */ | 114 | */ |
115 | #define MAC_ADDR_LEN 6 /* in bytes */ | 115 | #define MAC_ADDR_LEN 6 /* in bytes */ |
116 | #define IP_ADDR_LEN 4 /* in bytes */ | 116 | #define IP_ADDR_LEN 4 /* in bytes */ |
117 | #define IPv6_ADDR_LEN 16 /* IPv6 address size */ | ||
117 | #define DRIVER_NAME "qla4xxx" | 118 | #define DRIVER_NAME "qla4xxx" |
118 | 119 | ||
119 | #define MAX_LINKED_CMDS_PER_LUN 3 | 120 | #define MAX_LINKED_CMDS_PER_LUN 3 |
@@ -220,7 +221,7 @@ struct ddb_entry { | |||
220 | 221 | ||
221 | uint16_t os_target_id; /* Target ID */ | 222 | uint16_t os_target_id; /* Target ID */ |
222 | uint16_t fw_ddb_index; /* DDB firmware index */ | 223 | uint16_t fw_ddb_index; /* DDB firmware index */ |
223 | uint8_t reserved[2]; | 224 | uint16_t options; |
224 | uint32_t fw_ddb_device_state; /* F/W Device State -- see ql4_fw.h */ | 225 | uint32_t fw_ddb_device_state; /* F/W Device State -- see ql4_fw.h */ |
225 | 226 | ||
226 | uint32_t CmdSn; | 227 | uint32_t CmdSn; |
@@ -245,10 +246,18 @@ struct ddb_entry { | |||
245 | 246 | ||
246 | uint16_t port; | 247 | uint16_t port; |
247 | uint32_t tpgt; | 248 | uint32_t tpgt; |
248 | uint8_t ip_addr[ISCSI_IPADDR_SIZE]; | 249 | uint8_t ip_addr[IP_ADDR_LEN]; |
249 | uint8_t iscsi_name[ISCSI_NAME_SIZE]; /* 72 x48 */ | 250 | uint8_t iscsi_name[ISCSI_NAME_SIZE]; /* 72 x48 */ |
250 | uint8_t iscsi_alias[0x20]; | 251 | uint8_t iscsi_alias[0x20]; |
251 | uint8_t isid[6]; | 252 | uint8_t isid[6]; |
253 | uint16_t iscsi_max_burst_len; | ||
254 | uint16_t iscsi_max_outsnd_r2t; | ||
255 | uint16_t iscsi_first_burst_len; | ||
256 | uint16_t iscsi_max_rcv_data_seg_len; | ||
257 | uint16_t iscsi_max_snd_data_seg_len; | ||
258 | |||
259 | struct in6_addr remote_ipv6_addr; | ||
260 | struct in6_addr link_local_ipv6_addr; | ||
252 | }; | 261 | }; |
253 | 262 | ||
254 | /* | 263 | /* |
@@ -441,8 +450,35 @@ struct scsi_qla_host { | |||
441 | 450 | ||
442 | /* Saved srb for status continuation entry processing */ | 451 | /* Saved srb for status continuation entry processing */ |
443 | struct srb *status_srb; | 452 | struct srb *status_srb; |
453 | |||
454 | /* IPv6 support info from InitFW */ | ||
455 | uint8_t acb_version; | ||
456 | uint8_t ipv4_addr_state; | ||
457 | uint16_t ipv4_options; | ||
458 | |||
459 | uint32_t resvd2; | ||
460 | uint32_t ipv6_options; | ||
461 | uint32_t ipv6_addl_options; | ||
462 | uint8_t ipv6_link_local_state; | ||
463 | uint8_t ipv6_addr0_state; | ||
464 | uint8_t ipv6_addr1_state; | ||
465 | uint8_t ipv6_default_router_state; | ||
466 | struct in6_addr ipv6_link_local_addr; | ||
467 | struct in6_addr ipv6_addr0; | ||
468 | struct in6_addr ipv6_addr1; | ||
469 | struct in6_addr ipv6_default_router_addr; | ||
444 | }; | 470 | }; |
445 | 471 | ||
472 | static inline int is_ipv4_enabled(struct scsi_qla_host *ha) | ||
473 | { | ||
474 | return ((ha->ipv4_options & IPOPT_IPv4_PROTOCOL_ENABLE) != 0); | ||
475 | } | ||
476 | |||
477 | static inline int is_ipv6_enabled(struct scsi_qla_host *ha) | ||
478 | { | ||
479 | return ((ha->ipv6_options & IPV6_OPT_IPV6_PROTOCOL_ENABLE) != 0); | ||
480 | } | ||
481 | |||
446 | static inline int is_qla4010(struct scsi_qla_host *ha) | 482 | static inline int is_qla4010(struct scsi_qla_host *ha) |
447 | { | 483 | { |
448 | return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4010; | 484 | return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4010; |
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h index 9cd7a608df38..dfe7b4dd3912 100644 --- a/drivers/scsi/qla4xxx/ql4_fw.h +++ b/drivers/scsi/qla4xxx/ql4_fw.h | |||
@@ -258,13 +258,15 @@ union external_hw_config_reg { | |||
258 | /* Mailbox 1 */ | 258 | /* Mailbox 1 */ |
259 | #define FW_STATE_READY 0x0000 | 259 | #define FW_STATE_READY 0x0000 |
260 | #define FW_STATE_CONFIG_WAIT 0x0001 | 260 | #define FW_STATE_CONFIG_WAIT 0x0001 |
261 | #define FW_STATE_WAIT_LOGIN 0x0002 | 261 | #define FW_STATE_WAIT_AUTOCONNECT 0x0002 |
262 | #define FW_STATE_ERROR 0x0004 | 262 | #define FW_STATE_ERROR 0x0004 |
263 | #define FW_STATE_DHCP_IN_PROGRESS 0x0008 | 263 | #define FW_STATE_CONFIGURING_IP 0x0008 |
264 | 264 | ||
265 | /* Mailbox 3 */ | 265 | /* Mailbox 3 */ |
266 | #define FW_ADDSTATE_OPTICAL_MEDIA 0x0001 | 266 | #define FW_ADDSTATE_OPTICAL_MEDIA 0x0001 |
267 | #define FW_ADDSTATE_DHCP_ENABLED 0x0002 | 267 | #define FW_ADDSTATE_DHCPv4_ENABLED 0x0002 |
268 | #define FW_ADDSTATE_DHCPv4_LEASE_ACQUIRED 0x0004 | ||
269 | #define FW_ADDSTATE_DHCPv4_LEASE_EXPIRED 0x0008 | ||
268 | #define FW_ADDSTATE_LINK_UP 0x0010 | 270 | #define FW_ADDSTATE_LINK_UP 0x0010 |
269 | #define FW_ADDSTATE_ISNS_SVC_ENABLED 0x0020 | 271 | #define FW_ADDSTATE_ISNS_SVC_ENABLED 0x0020 |
270 | #define MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS 0x006B | 272 | #define MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS 0x006B |
@@ -320,6 +322,8 @@ union external_hw_config_reg { | |||
320 | /* Host Adapter Initialization Control Block (from host) */ | 322 | /* Host Adapter Initialization Control Block (from host) */ |
321 | struct addr_ctrl_blk { | 323 | struct addr_ctrl_blk { |
322 | uint8_t version; /* 00 */ | 324 | uint8_t version; /* 00 */ |
325 | #define IFCB_VER_MIN 0x01 | ||
326 | #define IFCB_VER_MAX 0x02 | ||
323 | uint8_t control; /* 01 */ | 327 | uint8_t control; /* 01 */ |
324 | 328 | ||
325 | uint16_t fw_options; /* 02-03 */ | 329 | uint16_t fw_options; /* 02-03 */ |
@@ -351,11 +355,16 @@ struct addr_ctrl_blk { | |||
351 | uint16_t iscsi_opts; /* 30-31 */ | 355 | uint16_t iscsi_opts; /* 30-31 */ |
352 | uint16_t ipv4_tcp_opts; /* 32-33 */ | 356 | uint16_t ipv4_tcp_opts; /* 32-33 */ |
353 | uint16_t ipv4_ip_opts; /* 34-35 */ | 357 | uint16_t ipv4_ip_opts; /* 34-35 */ |
358 | #define IPOPT_IPv4_PROTOCOL_ENABLE 0x8000 | ||
354 | 359 | ||
355 | uint16_t iscsi_max_pdu_size; /* 36-37 */ | 360 | uint16_t iscsi_max_pdu_size; /* 36-37 */ |
356 | uint8_t ipv4_tos; /* 38 */ | 361 | uint8_t ipv4_tos; /* 38 */ |
357 | uint8_t ipv4_ttl; /* 39 */ | 362 | uint8_t ipv4_ttl; /* 39 */ |
358 | uint8_t acb_version; /* 3A */ | 363 | uint8_t acb_version; /* 3A */ |
364 | #define ACB_NOT_SUPPORTED 0x00 | ||
365 | #define ACB_SUPPORTED 0x02 /* Capable of ACB Version 2 | ||
366 | Features */ | ||
367 | |||
359 | uint8_t res2; /* 3B */ | 368 | uint8_t res2; /* 3B */ |
360 | uint16_t def_timeout; /* 3C-3D */ | 369 | uint16_t def_timeout; /* 3C-3D */ |
361 | uint16_t iscsi_fburst_len; /* 3E-3F */ | 370 | uint16_t iscsi_fburst_len; /* 3E-3F */ |
@@ -397,16 +406,35 @@ struct addr_ctrl_blk { | |||
397 | uint32_t cookie; /* 200-203 */ | 406 | uint32_t cookie; /* 200-203 */ |
398 | uint16_t ipv6_port; /* 204-205 */ | 407 | uint16_t ipv6_port; /* 204-205 */ |
399 | uint16_t ipv6_opts; /* 206-207 */ | 408 | uint16_t ipv6_opts; /* 206-207 */ |
409 | #define IPV6_OPT_IPV6_PROTOCOL_ENABLE 0x8000 | ||
410 | |||
400 | uint16_t ipv6_addtl_opts; /* 208-209 */ | 411 | uint16_t ipv6_addtl_opts; /* 208-209 */ |
412 | #define IPV6_ADDOPT_NEIGHBOR_DISCOVERY_ADDR_ENABLE 0x0002 /* Pri ACB | ||
413 | Only */ | ||
414 | #define IPV6_ADDOPT_AUTOCONFIG_LINK_LOCAL_ADDR 0x0001 | ||
415 | |||
401 | uint16_t ipv6_tcp_opts; /* 20A-20B */ | 416 | uint16_t ipv6_tcp_opts; /* 20A-20B */ |
402 | uint8_t ipv6_tcp_wsf; /* 20C */ | 417 | uint8_t ipv6_tcp_wsf; /* 20C */ |
403 | uint16_t ipv6_flow_lbl; /* 20D-20F */ | 418 | uint16_t ipv6_flow_lbl; /* 20D-20F */ |
404 | uint8_t ipv6_gw_addr[16]; /* 210-21F */ | 419 | uint8_t ipv6_dflt_rtr_addr[16]; /* 210-21F */ |
405 | uint16_t ipv6_vlan_tag; /* 220-221 */ | 420 | uint16_t ipv6_vlan_tag; /* 220-221 */ |
406 | uint8_t ipv6_lnk_lcl_addr_state;/* 222 */ | 421 | uint8_t ipv6_lnk_lcl_addr_state;/* 222 */ |
407 | uint8_t ipv6_addr0_state; /* 223 */ | 422 | uint8_t ipv6_addr0_state; /* 223 */ |
408 | uint8_t ipv6_addr1_state; /* 224 */ | 423 | uint8_t ipv6_addr1_state; /* 224 */ |
409 | uint8_t ipv6_gw_state; /* 225 */ | 424 | #define IP_ADDRSTATE_UNCONFIGURED 0 |
425 | #define IP_ADDRSTATE_INVALID 1 | ||
426 | #define IP_ADDRSTATE_ACQUIRING 2 | ||
427 | #define IP_ADDRSTATE_TENTATIVE 3 | ||
428 | #define IP_ADDRSTATE_DEPRICATED 4 | ||
429 | #define IP_ADDRSTATE_PREFERRED 5 | ||
430 | #define IP_ADDRSTATE_DISABLING 6 | ||
431 | |||
432 | uint8_t ipv6_dflt_rtr_state; /* 225 */ | ||
433 | #define IPV6_RTRSTATE_UNKNOWN 0 | ||
434 | #define IPV6_RTRSTATE_MANUAL 1 | ||
435 | #define IPV6_RTRSTATE_ADVERTISED 3 | ||
436 | #define IPV6_RTRSTATE_STALE 4 | ||
437 | |||
410 | uint8_t ipv6_traffic_class; /* 226 */ | 438 | uint8_t ipv6_traffic_class; /* 226 */ |
411 | uint8_t ipv6_hop_limit; /* 227 */ | 439 | uint8_t ipv6_hop_limit; /* 227 */ |
412 | uint8_t ipv6_if_id[8]; /* 228-22F */ | 440 | uint8_t ipv6_if_id[8]; /* 228-22F */ |
@@ -424,7 +452,7 @@ struct addr_ctrl_blk { | |||
424 | 452 | ||
425 | struct init_fw_ctrl_blk { | 453 | struct init_fw_ctrl_blk { |
426 | struct addr_ctrl_blk pri; | 454 | struct addr_ctrl_blk pri; |
427 | struct addr_ctrl_blk sec; | 455 | /* struct addr_ctrl_blk sec;*/ |
428 | }; | 456 | }; |
429 | 457 | ||
430 | /*************************************************************************/ | 458 | /*************************************************************************/ |
@@ -433,6 +461,9 @@ struct dev_db_entry { | |||
433 | uint16_t options; /* 00-01 */ | 461 | uint16_t options; /* 00-01 */ |
434 | #define DDB_OPT_DISC_SESSION 0x10 | 462 | #define DDB_OPT_DISC_SESSION 0x10 |
435 | #define DDB_OPT_TARGET 0x02 /* device is a target */ | 463 | #define DDB_OPT_TARGET 0x02 /* device is a target */ |
464 | #define DDB_OPT_IPV6_DEVICE 0x100 | ||
465 | #define DDB_OPT_IPV6_NULL_LINK_LOCAL 0x800 /* post connection */ | ||
466 | #define DDB_OPT_IPV6_FW_DEFINED_LINK_LOCAL 0x800 /* pre connection */ | ||
436 | 467 | ||
437 | uint16_t exec_throttle; /* 02-03 */ | 468 | uint16_t exec_throttle; /* 02-03 */ |
438 | uint16_t exec_count; /* 04-05 */ | 469 | uint16_t exec_count; /* 04-05 */ |
@@ -468,7 +499,7 @@ struct dev_db_entry { | |||
468 | * pointer to a string so we | 499 | * pointer to a string so we |
469 | * don't have to reserve soooo | 500 | * don't have to reserve soooo |
470 | * much RAM */ | 501 | * much RAM */ |
471 | uint8_t ipv6_addr[0x10];/* 1A0-1AF */ | 502 | uint8_t link_local_ipv6_addr[0x10]; /* 1A0-1AF */ |
472 | uint8_t res5[0x10]; /* 1B0-1BF */ | 503 | uint8_t res5[0x10]; /* 1B0-1BF */ |
473 | uint16_t ddb_link; /* 1C0-1C1 */ | 504 | uint16_t ddb_link; /* 1C0-1C1 */ |
474 | uint16_t chap_tbl_idx; /* 1C2-1C3 */ | 505 | uint16_t chap_tbl_idx; /* 1C2-1C3 */ |
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index 92329a461c68..36ec02c49a1b 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c | |||
@@ -189,6 +189,78 @@ static int qla4xxx_init_local_data(struct scsi_qla_host *ha) | |||
189 | return qla4xxx_get_firmware_status(ha); | 189 | return qla4xxx_get_firmware_status(ha); |
190 | } | 190 | } |
191 | 191 | ||
192 | static uint8_t | ||
193 | qla4xxx_wait_for_ip_config(struct scsi_qla_host *ha) | ||
194 | { | ||
195 | uint8_t ipv4_wait = 0; | ||
196 | uint8_t ipv6_wait = 0; | ||
197 | int8_t ip_address[IPv6_ADDR_LEN] = {0} ; | ||
198 | |||
199 | /* If both IPv4 & IPv6 are enabled, possibly only one | ||
200 | * IP address may be acquired, so check to see if we | ||
201 | * need to wait for another */ | ||
202 | if (is_ipv4_enabled(ha) && is_ipv6_enabled(ha)) { | ||
203 | if (((ha->addl_fw_state & FW_ADDSTATE_DHCPv4_ENABLED) != 0) && | ||
204 | ((ha->addl_fw_state & | ||
205 | FW_ADDSTATE_DHCPv4_LEASE_ACQUIRED) == 0)) { | ||
206 | ipv4_wait = 1; | ||
207 | } | ||
208 | if (((ha->ipv6_addl_options & | ||
209 | IPV6_ADDOPT_NEIGHBOR_DISCOVERY_ADDR_ENABLE) != 0) && | ||
210 | ((ha->ipv6_link_local_state == IP_ADDRSTATE_ACQUIRING) || | ||
211 | (ha->ipv6_addr0_state == IP_ADDRSTATE_ACQUIRING) || | ||
212 | (ha->ipv6_addr1_state == IP_ADDRSTATE_ACQUIRING))) { | ||
213 | |||
214 | ipv6_wait = 1; | ||
215 | |||
216 | if ((ha->ipv6_link_local_state == | ||
217 | IP_ADDRSTATE_PREFERRED) || | ||
218 | (ha->ipv6_addr0_state == IP_ADDRSTATE_PREFERRED) || | ||
219 | (ha->ipv6_addr1_state == IP_ADDRSTATE_PREFERRED)) { | ||
220 | DEBUG2(printk(KERN_INFO "scsi%ld: %s: " | ||
221 | "Preferred IP configured." | ||
222 | " Don't wait!\n", ha->host_no, | ||
223 | __func__)); | ||
224 | ipv6_wait = 0; | ||
225 | } | ||
226 | if (memcmp(&ha->ipv6_default_router_addr, ip_address, | ||
227 | IPv6_ADDR_LEN) == 0) { | ||
228 | DEBUG2(printk(KERN_INFO "scsi%ld: %s: " | ||
229 | "No Router configured. " | ||
230 | "Don't wait!\n", ha->host_no, | ||
231 | __func__)); | ||
232 | ipv6_wait = 0; | ||
233 | } | ||
234 | if ((ha->ipv6_default_router_state == | ||
235 | IPV6_RTRSTATE_MANUAL) && | ||
236 | (ha->ipv6_link_local_state == | ||
237 | IP_ADDRSTATE_TENTATIVE) && | ||
238 | (memcmp(&ha->ipv6_link_local_addr, | ||
239 | &ha->ipv6_default_router_addr, 4) == 0)) { | ||
240 | DEBUG2(printk("scsi%ld: %s: LinkLocal Router & " | ||
241 | "IP configured. Don't wait!\n", | ||
242 | ha->host_no, __func__)); | ||
243 | ipv6_wait = 0; | ||
244 | } | ||
245 | } | ||
246 | if (ipv4_wait || ipv6_wait) { | ||
247 | DEBUG2(printk("scsi%ld: %s: Wait for additional " | ||
248 | "IP(s) \"", ha->host_no, __func__)); | ||
249 | if (ipv4_wait) | ||
250 | DEBUG2(printk("IPv4 ")); | ||
251 | if (ha->ipv6_link_local_state == IP_ADDRSTATE_ACQUIRING) | ||
252 | DEBUG2(printk("IPv6LinkLocal ")); | ||
253 | if (ha->ipv6_addr0_state == IP_ADDRSTATE_ACQUIRING) | ||
254 | DEBUG2(printk("IPv6Addr0 ")); | ||
255 | if (ha->ipv6_addr1_state == IP_ADDRSTATE_ACQUIRING) | ||
256 | DEBUG2(printk("IPv6Addr1 ")); | ||
257 | DEBUG2(printk("\"\n")); | ||
258 | } | ||
259 | } | ||
260 | |||
261 | return ipv4_wait|ipv6_wait; | ||
262 | } | ||
263 | |||
192 | static int qla4xxx_fw_ready(struct scsi_qla_host *ha) | 264 | static int qla4xxx_fw_ready(struct scsi_qla_host *ha) |
193 | { | 265 | { |
194 | uint32_t timeout_count; | 266 | uint32_t timeout_count; |
@@ -226,38 +298,80 @@ static int qla4xxx_fw_ready(struct scsi_qla_host *ha) | |||
226 | continue; | 298 | continue; |
227 | } | 299 | } |
228 | 300 | ||
301 | if (ha->firmware_state & FW_STATE_WAIT_AUTOCONNECT) { | ||
302 | DEBUG2(printk(KERN_INFO "scsi%ld: %s: fwstate:" | ||
303 | "AUTOCONNECT in progress\n", | ||
304 | ha->host_no, __func__)); | ||
305 | } | ||
306 | |||
307 | if (ha->firmware_state & FW_STATE_CONFIGURING_IP) { | ||
308 | DEBUG2(printk(KERN_INFO "scsi%ld: %s: fwstate:" | ||
309 | " CONFIGURING IP\n", | ||
310 | ha->host_no, __func__)); | ||
311 | /* | ||
312 | * Check for link state after 15 secs and if link is | ||
313 | * still DOWN then, cable is unplugged. Ignore "DHCP | ||
314 | * in Progress/CONFIGURING IP" bit to check if firmware | ||
315 | * is in ready state or not after 15 secs. | ||
316 | * This is applicable for both 2.x & 3.x firmware | ||
317 | */ | ||
318 | if (timeout_count <= (ADAPTER_INIT_TOV - 15)) { | ||
319 | if (ha->addl_fw_state & FW_ADDSTATE_LINK_UP) { | ||
320 | DEBUG2(printk(KERN_INFO "scsi%ld: %s:" | ||
321 | " LINK UP (Cable plugged)\n", | ||
322 | ha->host_no, __func__)); | ||
323 | } else if (ha->firmware_state & | ||
324 | (FW_STATE_CONFIGURING_IP | | ||
325 | FW_STATE_READY)) { | ||
326 | DEBUG2(printk(KERN_INFO "scsi%ld: %s: " | ||
327 | "LINK DOWN (Cable unplugged)\n", | ||
328 | ha->host_no, __func__)); | ||
329 | ha->firmware_state = FW_STATE_READY; | ||
330 | } | ||
331 | } | ||
332 | } | ||
333 | |||
229 | if (ha->firmware_state == FW_STATE_READY) { | 334 | if (ha->firmware_state == FW_STATE_READY) { |
230 | DEBUG2(dev_info(&ha->pdev->dev, "Firmware Ready..\n")); | 335 | /* If DHCP IP Addr is available, retrieve it now. */ |
231 | /* The firmware is ready to process SCSI commands. */ | 336 | if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, |
232 | DEBUG2(dev_info(&ha->pdev->dev, | 337 | &ha->dpc_flags)) |
233 | "scsi%ld: %s: MEDIA TYPE - %s\n", | 338 | qla4xxx_get_dhcp_ip_address(ha); |
234 | ha->host_no, | 339 | |
235 | __func__, (ha->addl_fw_state & | 340 | if (!qla4xxx_wait_for_ip_config(ha) || |
236 | FW_ADDSTATE_OPTICAL_MEDIA) | 341 | timeout_count == 1) { |
237 | != 0 ? "OPTICAL" : "COPPER")); | 342 | DEBUG2(dev_info(&ha->pdev->dev, |
238 | DEBUG2(dev_info(&ha->pdev->dev, | 343 | "Firmware Ready..\n")); |
239 | "scsi%ld: %s: DHCP STATE Enabled " | 344 | /* The firmware is ready to process SCSI |
240 | "%s\n", | 345 | commands. */ |
241 | ha->host_no, __func__, | 346 | DEBUG2(dev_info(&ha->pdev->dev, |
242 | (ha->addl_fw_state & | 347 | "scsi%ld: %s: MEDIA TYPE" |
243 | FW_ADDSTATE_DHCP_ENABLED) != 0 ? | 348 | " - %s\n", ha->host_no, |
244 | "YES" : "NO")); | 349 | __func__, (ha->addl_fw_state & |
245 | DEBUG2(dev_info(&ha->pdev->dev, | 350 | FW_ADDSTATE_OPTICAL_MEDIA) |
246 | "scsi%ld: %s: LINK %s\n", | 351 | != 0 ? "OPTICAL" : "COPPER")); |
247 | ha->host_no, __func__, | 352 | DEBUG2(dev_info(&ha->pdev->dev, |
248 | (ha->addl_fw_state & | 353 | "scsi%ld: %s: DHCPv4 STATE" |
249 | FW_ADDSTATE_LINK_UP) != 0 ? | 354 | " Enabled %s\n", ha->host_no, |
250 | "UP" : "DOWN")); | 355 | __func__, (ha->addl_fw_state & |
251 | DEBUG2(dev_info(&ha->pdev->dev, | 356 | FW_ADDSTATE_DHCPv4_ENABLED) != 0 ? |
252 | "scsi%ld: %s: iSNS Service " | 357 | "YES" : "NO")); |
253 | "Started %s\n", | 358 | DEBUG2(dev_info(&ha->pdev->dev, |
254 | ha->host_no, __func__, | 359 | "scsi%ld: %s: LINK %s\n", |
255 | (ha->addl_fw_state & | 360 | ha->host_no, __func__, |
256 | FW_ADDSTATE_ISNS_SVC_ENABLED) != 0 ? | 361 | (ha->addl_fw_state & |
257 | "YES" : "NO")); | 362 | FW_ADDSTATE_LINK_UP) != 0 ? |
258 | 363 | "UP" : "DOWN")); | |
259 | ready = 1; | 364 | DEBUG2(dev_info(&ha->pdev->dev, |
260 | break; | 365 | "scsi%ld: %s: iSNS Service " |
366 | "Started %s\n", | ||
367 | ha->host_no, __func__, | ||
368 | (ha->addl_fw_state & | ||
369 | FW_ADDSTATE_ISNS_SVC_ENABLED) != 0 ? | ||
370 | "YES" : "NO")); | ||
371 | |||
372 | ready = 1; | ||
373 | break; | ||
374 | } | ||
261 | } | 375 | } |
262 | DEBUG2(printk("scsi%ld: %s: waiting on fw, state=%x:%x - " | 376 | DEBUG2(printk("scsi%ld: %s: waiting on fw, state=%x:%x - " |
263 | "seconds expired= %d\n", ha->host_no, __func__, | 377 | "seconds expired= %d\n", ha->host_no, __func__, |
@@ -272,15 +386,19 @@ static int qla4xxx_fw_ready(struct scsi_qla_host *ha) | |||
272 | msleep(1000); | 386 | msleep(1000); |
273 | } /* end of for */ | 387 | } /* end of for */ |
274 | 388 | ||
275 | if (timeout_count == 0) | 389 | if (timeout_count <= 0) |
276 | DEBUG2(printk("scsi%ld: %s: FW Initialization timed out!\n", | 390 | DEBUG2(printk("scsi%ld: %s: FW Initialization timed out!\n", |
277 | ha->host_no, __func__)); | 391 | ha->host_no, __func__)); |
278 | 392 | ||
279 | if (ha->firmware_state & FW_STATE_DHCP_IN_PROGRESS) { | 393 | if (ha->firmware_state & FW_STATE_CONFIGURING_IP) { |
280 | DEBUG2(printk("scsi%ld: %s: FW is reporting its waiting to" | 394 | DEBUG2(printk("scsi%ld: %s: FW initialized, but is reporting " |
281 | " grab an IP address from DHCP server\n", | 395 | "it's waiting to configure an IP address\n", |
282 | ha->host_no, __func__)); | 396 | ha->host_no, __func__)); |
283 | ready = 1; | 397 | ready = 1; |
398 | } else if (ha->firmware_state & FW_STATE_WAIT_AUTOCONNECT) { | ||
399 | DEBUG2(printk("scsi%ld: %s: FW initialized, but " | ||
400 | "auto-discovery still in process\n", | ||
401 | ha->host_no, __func__)); | ||
284 | } | 402 | } |
285 | 403 | ||
286 | return ready; | 404 | return ready; |
@@ -419,6 +537,7 @@ static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha, | |||
419 | } | 537 | } |
420 | 538 | ||
421 | status = QLA_SUCCESS; | 539 | status = QLA_SUCCESS; |
540 | ddb_entry->options = le16_to_cpu(fw_ddb_entry->options); | ||
422 | ddb_entry->target_session_id = le16_to_cpu(fw_ddb_entry->tsid); | 541 | ddb_entry->target_session_id = le16_to_cpu(fw_ddb_entry->tsid); |
423 | ddb_entry->task_mgmt_timeout = | 542 | ddb_entry->task_mgmt_timeout = |
424 | le16_to_cpu(fw_ddb_entry->def_timeout); | 543 | le16_to_cpu(fw_ddb_entry->def_timeout); |
@@ -442,11 +561,30 @@ static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha, | |||
442 | memcpy(&ddb_entry->ip_addr[0], &fw_ddb_entry->ip_addr[0], | 561 | memcpy(&ddb_entry->ip_addr[0], &fw_ddb_entry->ip_addr[0], |
443 | min(sizeof(ddb_entry->ip_addr), sizeof(fw_ddb_entry->ip_addr))); | 562 | min(sizeof(ddb_entry->ip_addr), sizeof(fw_ddb_entry->ip_addr))); |
444 | 563 | ||
564 | ddb_entry->iscsi_max_burst_len = fw_ddb_entry->iscsi_max_burst_len; | ||
565 | ddb_entry->iscsi_max_outsnd_r2t = fw_ddb_entry->iscsi_max_outsnd_r2t; | ||
566 | ddb_entry->iscsi_first_burst_len = fw_ddb_entry->iscsi_first_burst_len; | ||
567 | ddb_entry->iscsi_max_rcv_data_seg_len = | ||
568 | fw_ddb_entry->iscsi_max_rcv_data_seg_len; | ||
569 | ddb_entry->iscsi_max_snd_data_seg_len = | ||
570 | fw_ddb_entry->iscsi_max_snd_data_seg_len; | ||
571 | |||
572 | if (ddb_entry->options & DDB_OPT_IPV6_DEVICE) { | ||
573 | memcpy(&ddb_entry->remote_ipv6_addr, | ||
574 | fw_ddb_entry->ip_addr, | ||
575 | min(sizeof(ddb_entry->remote_ipv6_addr), | ||
576 | sizeof(fw_ddb_entry->ip_addr))); | ||
577 | memcpy(&ddb_entry->link_local_ipv6_addr, | ||
578 | fw_ddb_entry->link_local_ipv6_addr, | ||
579 | min(sizeof(ddb_entry->link_local_ipv6_addr), | ||
580 | sizeof(fw_ddb_entry->link_local_ipv6_addr))); | ||
581 | } | ||
582 | |||
445 | DEBUG2(printk("scsi%ld: %s: ddb[%d] - State= %x status= %d.\n", | 583 | DEBUG2(printk("scsi%ld: %s: ddb[%d] - State= %x status= %d.\n", |
446 | ha->host_no, __func__, fw_ddb_index, | 584 | ha->host_no, __func__, fw_ddb_index, |
447 | ddb_entry->fw_ddb_device_state, status)); | 585 | ddb_entry->fw_ddb_device_state, status)); |
448 | 586 | ||
449 | exit_update_ddb: | 587 | exit_update_ddb: |
450 | if (fw_ddb_entry) | 588 | if (fw_ddb_entry) |
451 | dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), | 589 | dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), |
452 | fw_ddb_entry, fw_ddb_entry_dma); | 590 | fw_ddb_entry, fw_ddb_entry_dma); |
@@ -1166,7 +1304,7 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, | |||
1166 | * the ddb_list and wait for DHCP lease acquired aen to come in | 1304 | * the ddb_list and wait for DHCP lease acquired aen to come in |
1167 | * followed by 0x8014 aen" to trigger the tgt discovery process. | 1305 | * followed by 0x8014 aen" to trigger the tgt discovery process. |
1168 | */ | 1306 | */ |
1169 | if (ha->firmware_state & FW_STATE_DHCP_IN_PROGRESS) | 1307 | if (ha->firmware_state & FW_STATE_CONFIGURING_IP) |
1170 | goto exit_init_online; | 1308 | goto exit_init_online; |
1171 | 1309 | ||
1172 | /* Skip device discovery if ip and subnet is zero */ | 1310 | /* Skip device discovery if ip and subnet is zero */ |
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index 09d6d4b76f39..43581ce3a1b6 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c | |||
@@ -172,108 +172,207 @@ mbox_exit: | |||
172 | return status; | 172 | return status; |
173 | } | 173 | } |
174 | 174 | ||
175 | uint8_t | ||
176 | qla4xxx_set_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd, | ||
177 | uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma) | ||
178 | { | ||
179 | memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT); | ||
180 | memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT); | ||
181 | mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE; | ||
182 | mbox_cmd[1] = 0; | ||
183 | mbox_cmd[2] = LSDW(init_fw_cb_dma); | ||
184 | mbox_cmd[3] = MSDW(init_fw_cb_dma); | ||
185 | mbox_cmd[4] = sizeof(struct addr_ctrl_blk); | ||
186 | mbox_cmd[5] = (IFCB_VER_MAX << 8) | IFCB_VER_MIN; | ||
187 | |||
188 | if (qla4xxx_mailbox_command(ha, 6, 6, mbox_cmd, mbox_sts) != | ||
189 | QLA_SUCCESS) { | ||
190 | DEBUG2(printk(KERN_WARNING "scsi%ld: %s: " | ||
191 | "MBOX_CMD_INITIALIZE_FIRMWARE" | ||
192 | " failed w/ status %04X\n", | ||
193 | ha->host_no, __func__, mbox_sts[0])); | ||
194 | return QLA_ERROR; | ||
195 | } | ||
196 | return QLA_SUCCESS; | ||
197 | } | ||
198 | |||
199 | uint8_t | ||
200 | qla4xxx_get_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd, | ||
201 | uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma) | ||
202 | { | ||
203 | memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT); | ||
204 | memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT); | ||
205 | mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK; | ||
206 | mbox_cmd[2] = LSDW(init_fw_cb_dma); | ||
207 | mbox_cmd[3] = MSDW(init_fw_cb_dma); | ||
208 | mbox_cmd[4] = sizeof(struct addr_ctrl_blk); | ||
209 | |||
210 | if (qla4xxx_mailbox_command(ha, 5, 5, mbox_cmd, mbox_sts) != | ||
211 | QLA_SUCCESS) { | ||
212 | DEBUG2(printk(KERN_WARNING "scsi%ld: %s: " | ||
213 | "MBOX_CMD_GET_INIT_FW_CTRL_BLOCK" | ||
214 | " failed w/ status %04X\n", | ||
215 | ha->host_no, __func__, mbox_sts[0])); | ||
216 | return QLA_ERROR; | ||
217 | } | ||
218 | return QLA_SUCCESS; | ||
219 | } | ||
220 | |||
221 | void | ||
222 | qla4xxx_update_local_ip(struct scsi_qla_host *ha, | ||
223 | struct addr_ctrl_blk *init_fw_cb) | ||
224 | { | ||
225 | /* Save IPv4 Address Info */ | ||
226 | memcpy(ha->ip_address, init_fw_cb->ipv4_addr, | ||
227 | min(sizeof(ha->ip_address), sizeof(init_fw_cb->ipv4_addr))); | ||
228 | memcpy(ha->subnet_mask, init_fw_cb->ipv4_subnet, | ||
229 | min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->ipv4_subnet))); | ||
230 | memcpy(ha->gateway, init_fw_cb->ipv4_gw_addr, | ||
231 | min(sizeof(ha->gateway), sizeof(init_fw_cb->ipv4_gw_addr))); | ||
232 | |||
233 | if (is_ipv6_enabled(ha)) { | ||
234 | /* Save IPv6 Address */ | ||
235 | ha->ipv6_link_local_state = init_fw_cb->ipv6_lnk_lcl_addr_state; | ||
236 | ha->ipv6_addr0_state = init_fw_cb->ipv6_addr0_state; | ||
237 | ha->ipv6_addr1_state = init_fw_cb->ipv6_addr1_state; | ||
238 | ha->ipv6_default_router_state = init_fw_cb->ipv6_dflt_rtr_state; | ||
239 | ha->ipv6_link_local_addr.in6_u.u6_addr8[0] = 0xFE; | ||
240 | ha->ipv6_link_local_addr.in6_u.u6_addr8[1] = 0x80; | ||
241 | |||
242 | memcpy(&ha->ipv6_link_local_addr.in6_u.u6_addr8[8], | ||
243 | init_fw_cb->ipv6_if_id, | ||
244 | min(sizeof(ha->ipv6_link_local_addr)/2, | ||
245 | sizeof(init_fw_cb->ipv6_if_id))); | ||
246 | memcpy(&ha->ipv6_addr0, init_fw_cb->ipv6_addr0, | ||
247 | min(sizeof(ha->ipv6_addr0), | ||
248 | sizeof(init_fw_cb->ipv6_addr0))); | ||
249 | memcpy(&ha->ipv6_addr1, init_fw_cb->ipv6_addr1, | ||
250 | min(sizeof(ha->ipv6_addr1), | ||
251 | sizeof(init_fw_cb->ipv6_addr1))); | ||
252 | memcpy(&ha->ipv6_default_router_addr, | ||
253 | init_fw_cb->ipv6_dflt_rtr_addr, | ||
254 | min(sizeof(ha->ipv6_default_router_addr), | ||
255 | sizeof(init_fw_cb->ipv6_dflt_rtr_addr))); | ||
256 | } | ||
257 | } | ||
258 | |||
259 | uint8_t | ||
260 | qla4xxx_update_local_ifcb(struct scsi_qla_host *ha, | ||
261 | uint32_t *mbox_cmd, | ||
262 | uint32_t *mbox_sts, | ||
263 | struct addr_ctrl_blk *init_fw_cb, | ||
264 | dma_addr_t init_fw_cb_dma) | ||
265 | { | ||
266 | if (qla4xxx_get_ifcb(ha, mbox_cmd, mbox_sts, init_fw_cb_dma) | ||
267 | != QLA_SUCCESS) { | ||
268 | DEBUG2(printk(KERN_WARNING | ||
269 | "scsi%ld: %s: Failed to get init_fw_ctrl_blk\n", | ||
270 | ha->host_no, __func__)); | ||
271 | return QLA_ERROR; | ||
272 | } | ||
273 | |||
274 | DEBUG2(qla4xxx_dump_buffer(init_fw_cb, sizeof(struct addr_ctrl_blk))); | ||
275 | |||
276 | /* Save some info in adapter structure. */ | ||
277 | ha->acb_version = init_fw_cb->acb_version; | ||
278 | ha->firmware_options = le16_to_cpu(init_fw_cb->fw_options); | ||
279 | ha->tcp_options = le16_to_cpu(init_fw_cb->ipv4_tcp_opts); | ||
280 | ha->ipv4_options = le16_to_cpu(init_fw_cb->ipv4_ip_opts); | ||
281 | ha->ipv4_addr_state = le16_to_cpu(init_fw_cb->ipv4_addr_state); | ||
282 | ha->heartbeat_interval = init_fw_cb->hb_interval; | ||
283 | memcpy(ha->name_string, init_fw_cb->iscsi_name, | ||
284 | min(sizeof(ha->name_string), | ||
285 | sizeof(init_fw_cb->iscsi_name))); | ||
286 | /*memcpy(ha->alias, init_fw_cb->Alias, | ||
287 | min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/ | ||
288 | |||
289 | /* Save Command Line Paramater info */ | ||
290 | ha->port_down_retry_count = le16_to_cpu(init_fw_cb->conn_ka_timeout); | ||
291 | ha->discovery_wait = ql4xdiscoverywait; | ||
292 | |||
293 | if (ha->acb_version == ACB_SUPPORTED) { | ||
294 | ha->ipv6_options = init_fw_cb->ipv6_opts; | ||
295 | ha->ipv6_addl_options = init_fw_cb->ipv6_addtl_opts; | ||
296 | } | ||
297 | qla4xxx_update_local_ip(ha, init_fw_cb); | ||
298 | |||
299 | return QLA_SUCCESS; | ||
300 | } | ||
301 | |||
175 | /** | 302 | /** |
176 | * qla4xxx_initialize_fw_cb - initializes firmware control block. | 303 | * qla4xxx_initialize_fw_cb - initializes firmware control block. |
177 | * @ha: Pointer to host adapter structure. | 304 | * @ha: Pointer to host adapter structure. |
178 | **/ | 305 | **/ |
179 | int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha) | 306 | int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha) |
180 | { | 307 | { |
181 | struct init_fw_ctrl_blk *init_fw_cb; | 308 | struct addr_ctrl_blk *init_fw_cb; |
182 | dma_addr_t init_fw_cb_dma; | 309 | dma_addr_t init_fw_cb_dma; |
183 | uint32_t mbox_cmd[MBOX_REG_COUNT]; | 310 | uint32_t mbox_cmd[MBOX_REG_COUNT]; |
184 | uint32_t mbox_sts[MBOX_REG_COUNT]; | 311 | uint32_t mbox_sts[MBOX_REG_COUNT]; |
185 | int status = QLA_ERROR; | 312 | int status = QLA_ERROR; |
186 | 313 | ||
187 | init_fw_cb = dma_alloc_coherent(&ha->pdev->dev, | 314 | init_fw_cb = dma_alloc_coherent(&ha->pdev->dev, |
188 | sizeof(struct init_fw_ctrl_blk), | 315 | sizeof(struct addr_ctrl_blk), |
189 | &init_fw_cb_dma, GFP_KERNEL); | 316 | &init_fw_cb_dma, GFP_KERNEL); |
190 | if (init_fw_cb == NULL) { | 317 | if (init_fw_cb == NULL) { |
191 | DEBUG2(printk("scsi%ld: %s: Unable to alloc init_cb\n", | 318 | DEBUG2(printk("scsi%ld: %s: Unable to alloc init_cb\n", |
192 | ha->host_no, __func__)); | 319 | ha->host_no, __func__)); |
193 | return 10; | 320 | return 10; |
194 | } | 321 | } |
195 | memset(init_fw_cb, 0, sizeof(struct init_fw_ctrl_blk)); | 322 | memset(init_fw_cb, 0, sizeof(struct addr_ctrl_blk)); |
196 | 323 | ||
197 | /* Get Initialize Firmware Control Block. */ | 324 | /* Get Initialize Firmware Control Block. */ |
198 | memset(&mbox_cmd, 0, sizeof(mbox_cmd)); | 325 | memset(&mbox_cmd, 0, sizeof(mbox_cmd)); |
199 | memset(&mbox_sts, 0, sizeof(mbox_sts)); | 326 | memset(&mbox_sts, 0, sizeof(mbox_sts)); |
200 | 327 | ||
201 | mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK; | 328 | if (qla4xxx_get_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) != |
202 | mbox_cmd[2] = LSDW(init_fw_cb_dma); | ||
203 | mbox_cmd[3] = MSDW(init_fw_cb_dma); | ||
204 | mbox_cmd[4] = sizeof(struct init_fw_ctrl_blk); | ||
205 | |||
206 | if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) != | ||
207 | QLA_SUCCESS) { | 329 | QLA_SUCCESS) { |
208 | dma_free_coherent(&ha->pdev->dev, | 330 | dma_free_coherent(&ha->pdev->dev, |
209 | sizeof(struct init_fw_ctrl_blk), | 331 | sizeof(struct addr_ctrl_blk), |
210 | init_fw_cb, init_fw_cb_dma); | 332 | init_fw_cb, init_fw_cb_dma); |
211 | return status; | 333 | goto exit_init_fw_cb; |
212 | } | 334 | } |
213 | 335 | ||
214 | /* Initialize request and response queues. */ | 336 | /* Initialize request and response queues. */ |
215 | qla4xxx_init_rings(ha); | 337 | qla4xxx_init_rings(ha); |
216 | 338 | ||
217 | /* Fill in the request and response queue information. */ | 339 | /* Fill in the request and response queue information. */ |
218 | init_fw_cb->pri.rqq_consumer_idx = cpu_to_le16(ha->request_out); | 340 | init_fw_cb->rqq_consumer_idx = cpu_to_le16(ha->request_out); |
219 | init_fw_cb->pri.compq_producer_idx = cpu_to_le16(ha->response_in); | 341 | init_fw_cb->compq_producer_idx = cpu_to_le16(ha->response_in); |
220 | init_fw_cb->pri.rqq_len = __constant_cpu_to_le16(REQUEST_QUEUE_DEPTH); | 342 | init_fw_cb->rqq_len = __constant_cpu_to_le16(REQUEST_QUEUE_DEPTH); |
221 | init_fw_cb->pri.compq_len = __constant_cpu_to_le16(RESPONSE_QUEUE_DEPTH); | 343 | init_fw_cb->compq_len = __constant_cpu_to_le16(RESPONSE_QUEUE_DEPTH); |
222 | init_fw_cb->pri.rqq_addr_lo = cpu_to_le32(LSDW(ha->request_dma)); | 344 | init_fw_cb->rqq_addr_lo = cpu_to_le32(LSDW(ha->request_dma)); |
223 | init_fw_cb->pri.rqq_addr_hi = cpu_to_le32(MSDW(ha->request_dma)); | 345 | init_fw_cb->rqq_addr_hi = cpu_to_le32(MSDW(ha->request_dma)); |
224 | init_fw_cb->pri.compq_addr_lo = cpu_to_le32(LSDW(ha->response_dma)); | 346 | init_fw_cb->compq_addr_lo = cpu_to_le32(LSDW(ha->response_dma)); |
225 | init_fw_cb->pri.compq_addr_hi = cpu_to_le32(MSDW(ha->response_dma)); | 347 | init_fw_cb->compq_addr_hi = cpu_to_le32(MSDW(ha->response_dma)); |
226 | init_fw_cb->pri.shdwreg_addr_lo = | 348 | init_fw_cb->shdwreg_addr_lo = cpu_to_le32(LSDW(ha->shadow_regs_dma)); |
227 | cpu_to_le32(LSDW(ha->shadow_regs_dma)); | 349 | init_fw_cb->shdwreg_addr_hi = cpu_to_le32(MSDW(ha->shadow_regs_dma)); |
228 | init_fw_cb->pri.shdwreg_addr_hi = | ||
229 | cpu_to_le32(MSDW(ha->shadow_regs_dma)); | ||
230 | 350 | ||
231 | /* Set up required options. */ | 351 | /* Set up required options. */ |
232 | init_fw_cb->pri.fw_options |= | 352 | init_fw_cb->fw_options |= |
233 | __constant_cpu_to_le16(FWOPT_SESSION_MODE | | 353 | __constant_cpu_to_le16(FWOPT_SESSION_MODE | |
234 | FWOPT_INITIATOR_MODE); | 354 | FWOPT_INITIATOR_MODE); |
235 | init_fw_cb->pri.fw_options &= __constant_cpu_to_le16(~FWOPT_TARGET_MODE); | 355 | init_fw_cb->fw_options &= __constant_cpu_to_le16(~FWOPT_TARGET_MODE); |
236 | 356 | ||
237 | /* Save some info in adapter structure. */ | 357 | if (qla4xxx_set_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) |
238 | ha->firmware_options = le16_to_cpu(init_fw_cb->pri.fw_options); | 358 | != QLA_SUCCESS) { |
239 | ha->tcp_options = le16_to_cpu(init_fw_cb->pri.ipv4_tcp_opts); | 359 | DEBUG2(printk(KERN_WARNING |
240 | ha->heartbeat_interval = init_fw_cb->pri.hb_interval; | 360 | "scsi%ld: %s: Failed to set init_fw_ctrl_blk\n", |
241 | memcpy(ha->ip_address, init_fw_cb->pri.ipv4_addr, | 361 | ha->host_no, __func__)); |
242 | min(sizeof(ha->ip_address), sizeof(init_fw_cb->pri.ipv4_addr))); | 362 | goto exit_init_fw_cb; |
243 | memcpy(ha->subnet_mask, init_fw_cb->pri.ipv4_subnet, | 363 | } |
244 | min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->pri.ipv4_subnet))); | ||
245 | memcpy(ha->gateway, init_fw_cb->pri.ipv4_gw_addr, | ||
246 | min(sizeof(ha->gateway), sizeof(init_fw_cb->pri.ipv4_gw_addr))); | ||
247 | memcpy(ha->name_string, init_fw_cb->pri.iscsi_name, | ||
248 | min(sizeof(ha->name_string), | ||
249 | sizeof(init_fw_cb->pri.iscsi_name))); | ||
250 | /*memcpy(ha->alias, init_fw_cb->Alias, | ||
251 | min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/ | ||
252 | |||
253 | /* Save Command Line Paramater info */ | ||
254 | ha->port_down_retry_count = le16_to_cpu(init_fw_cb->pri.conn_ka_timeout); | ||
255 | ha->discovery_wait = ql4xdiscoverywait; | ||
256 | |||
257 | /* Send Initialize Firmware Control Block. */ | ||
258 | memset(&mbox_cmd, 0, sizeof(mbox_cmd)); | ||
259 | memset(&mbox_sts, 0, sizeof(mbox_sts)); | ||
260 | |||
261 | mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE; | ||
262 | mbox_cmd[1] = 0; | ||
263 | mbox_cmd[2] = LSDW(init_fw_cb_dma); | ||
264 | mbox_cmd[3] = MSDW(init_fw_cb_dma); | ||
265 | mbox_cmd[4] = sizeof(struct init_fw_ctrl_blk); | ||
266 | 364 | ||
267 | if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) == | 365 | if (qla4xxx_update_local_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], |
268 | QLA_SUCCESS) | 366 | init_fw_cb, init_fw_cb_dma) != QLA_SUCCESS) { |
269 | status = QLA_SUCCESS; | 367 | DEBUG2(printk("scsi%ld: %s: Failed to update local ifcb\n", |
270 | else { | 368 | ha->host_no, __func__)); |
271 | DEBUG2(printk("scsi%ld: %s: MBOX_CMD_INITIALIZE_FIRMWARE " | 369 | goto exit_init_fw_cb; |
272 | "failed w/ status %04X\n", ha->host_no, __func__, | ||
273 | mbox_sts[0])); | ||
274 | } | 370 | } |
275 | dma_free_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk), | 371 | status = QLA_SUCCESS; |
276 | init_fw_cb, init_fw_cb_dma); | 372 | |
373 | exit_init_fw_cb: | ||
374 | dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk), | ||
375 | init_fw_cb, init_fw_cb_dma); | ||
277 | 376 | ||
278 | return status; | 377 | return status; |
279 | } | 378 | } |
@@ -284,13 +383,13 @@ int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha) | |||
284 | **/ | 383 | **/ |
285 | int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha) | 384 | int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha) |
286 | { | 385 | { |
287 | struct init_fw_ctrl_blk *init_fw_cb; | 386 | struct addr_ctrl_blk *init_fw_cb; |
288 | dma_addr_t init_fw_cb_dma; | 387 | dma_addr_t init_fw_cb_dma; |
289 | uint32_t mbox_cmd[MBOX_REG_COUNT]; | 388 | uint32_t mbox_cmd[MBOX_REG_COUNT]; |
290 | uint32_t mbox_sts[MBOX_REG_COUNT]; | 389 | uint32_t mbox_sts[MBOX_REG_COUNT]; |
291 | 390 | ||
292 | init_fw_cb = dma_alloc_coherent(&ha->pdev->dev, | 391 | init_fw_cb = dma_alloc_coherent(&ha->pdev->dev, |
293 | sizeof(struct init_fw_ctrl_blk), | 392 | sizeof(struct addr_ctrl_blk), |
294 | &init_fw_cb_dma, GFP_KERNEL); | 393 | &init_fw_cb_dma, GFP_KERNEL); |
295 | if (init_fw_cb == NULL) { | 394 | if (init_fw_cb == NULL) { |
296 | printk("scsi%ld: %s: Unable to alloc init_cb\n", ha->host_no, | 395 | printk("scsi%ld: %s: Unable to alloc init_cb\n", ha->host_no, |
@@ -299,35 +398,21 @@ int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha) | |||
299 | } | 398 | } |
300 | 399 | ||
301 | /* Get Initialize Firmware Control Block. */ | 400 | /* Get Initialize Firmware Control Block. */ |
302 | memset(&mbox_cmd, 0, sizeof(mbox_cmd)); | 401 | memset(init_fw_cb, 0, sizeof(struct addr_ctrl_blk)); |
303 | memset(&mbox_sts, 0, sizeof(mbox_sts)); | 402 | if (qla4xxx_get_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) != |
304 | |||
305 | memset(init_fw_cb, 0, sizeof(struct init_fw_ctrl_blk)); | ||
306 | mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK; | ||
307 | mbox_cmd[2] = LSDW(init_fw_cb_dma); | ||
308 | mbox_cmd[3] = MSDW(init_fw_cb_dma); | ||
309 | mbox_cmd[4] = sizeof(struct init_fw_ctrl_blk); | ||
310 | |||
311 | if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) != | ||
312 | QLA_SUCCESS) { | 403 | QLA_SUCCESS) { |
313 | DEBUG2(printk("scsi%ld: %s: Failed to get init_fw_ctrl_blk\n", | 404 | DEBUG2(printk("scsi%ld: %s: Failed to get init_fw_ctrl_blk\n", |
314 | ha->host_no, __func__)); | 405 | ha->host_no, __func__)); |
315 | dma_free_coherent(&ha->pdev->dev, | 406 | dma_free_coherent(&ha->pdev->dev, |
316 | sizeof(struct init_fw_ctrl_blk), | 407 | sizeof(struct addr_ctrl_blk), |
317 | init_fw_cb, init_fw_cb_dma); | 408 | init_fw_cb, init_fw_cb_dma); |
318 | return QLA_ERROR; | 409 | return QLA_ERROR; |
319 | } | 410 | } |
320 | 411 | ||
321 | /* Save IP Address. */ | 412 | /* Save IP Address. */ |
322 | memcpy(ha->ip_address, init_fw_cb->pri.ipv4_addr, | 413 | qla4xxx_update_local_ip(ha, init_fw_cb); |
323 | min(sizeof(ha->ip_address), sizeof(init_fw_cb->pri.ipv4_addr))); | 414 | dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk), |
324 | memcpy(ha->subnet_mask, init_fw_cb->pri.ipv4_subnet, | 415 | init_fw_cb, init_fw_cb_dma); |
325 | min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->pri.ipv4_subnet))); | ||
326 | memcpy(ha->gateway, init_fw_cb->pri.ipv4_gw_addr, | ||
327 | min(sizeof(ha->gateway), sizeof(init_fw_cb->pri.ipv4_gw_addr))); | ||
328 | |||
329 | dma_free_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk), | ||
330 | init_fw_cb, init_fw_cb_dma); | ||
331 | 416 | ||
332 | return QLA_SUCCESS; | 417 | return QLA_SUCCESS; |
333 | } | 418 | } |
@@ -409,6 +494,7 @@ int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha, | |||
409 | uint16_t *connection_id) | 494 | uint16_t *connection_id) |
410 | { | 495 | { |
411 | int status = QLA_ERROR; | 496 | int status = QLA_ERROR; |
497 | uint16_t options; | ||
412 | uint32_t mbox_cmd[MBOX_REG_COUNT]; | 498 | uint32_t mbox_cmd[MBOX_REG_COUNT]; |
413 | uint32_t mbox_sts[MBOX_REG_COUNT]; | 499 | uint32_t mbox_sts[MBOX_REG_COUNT]; |
414 | 500 | ||
@@ -441,14 +527,26 @@ int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha, | |||
441 | goto exit_get_fwddb; | 527 | goto exit_get_fwddb; |
442 | } | 528 | } |
443 | if (fw_ddb_entry) { | 529 | if (fw_ddb_entry) { |
444 | dev_info(&ha->pdev->dev, "DDB[%d] MB0 %04x Tot %d Next %d " | 530 | options = le16_to_cpu(fw_ddb_entry->options); |
445 | "State %04x ConnErr %08x %d.%d.%d.%d:%04d \"%s\"\n", | 531 | if (options & DDB_OPT_IPV6_DEVICE) { |
446 | fw_ddb_index, mbox_sts[0], mbox_sts[2], mbox_sts[3], | 532 | dev_info(&ha->pdev->dev, "%s: DDB[%d] MB0 %04x Tot %d " |
447 | mbox_sts[4], mbox_sts[5], fw_ddb_entry->ip_addr[0], | 533 | "Next %d State %04x ConnErr %08x %pI6 " |
448 | fw_ddb_entry->ip_addr[1], fw_ddb_entry->ip_addr[2], | 534 | ":%04d \"%s\"\n", __func__, fw_ddb_index, |
449 | fw_ddb_entry->ip_addr[3], | 535 | mbox_sts[0], mbox_sts[2], mbox_sts[3], |
450 | le16_to_cpu(fw_ddb_entry->port), | 536 | mbox_sts[4], mbox_sts[5], |
451 | fw_ddb_entry->iscsi_name); | 537 | fw_ddb_entry->ip_addr, |
538 | le16_to_cpu(fw_ddb_entry->port), | ||
539 | fw_ddb_entry->iscsi_name); | ||
540 | } else { | ||
541 | dev_info(&ha->pdev->dev, "%s: DDB[%d] MB0 %04x Tot %d " | ||
542 | "Next %d State %04x ConnErr %08x %pI4 " | ||
543 | ":%04d \"%s\"\n", __func__, fw_ddb_index, | ||
544 | mbox_sts[0], mbox_sts[2], mbox_sts[3], | ||
545 | mbox_sts[4], mbox_sts[5], | ||
546 | fw_ddb_entry->ip_addr, | ||
547 | le16_to_cpu(fw_ddb_entry->port), | ||
548 | fw_ddb_entry->iscsi_name); | ||
549 | } | ||
452 | } | 550 | } |
453 | if (num_valid_ddb_entries) | 551 | if (num_valid_ddb_entries) |
454 | *num_valid_ddb_entries = mbox_sts[2]; | 552 | *num_valid_ddb_entries = mbox_sts[2]; |