[SCSI] qla4xxx: Add support for additional network parameters settings

Added support to display and update additional network parameters
through iscsiadm.

Signed-off-by: Harish Zunjarrao <harish.zunjarrao@qlogic.com>
Signed-off-by: Adheer Chandravanshi <adheer.chandravanshi@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
Harish Zunjarrao 2013-10-18 09:01:42 -04:00 committed by James Bottomley
parent 3e0f65b34c
commit f8e9341224
6 changed files with 1212 additions and 133 deletions

View file

@ -179,6 +179,10 @@
n &= ~v; \
}
#define OP_STATE(o, f, p) { \
p = (o & f) ? "enable" : "disable"; \
}
/*
* Retry & Timeout Values
*/
@ -476,6 +480,34 @@ struct ipaddress_config {
uint16_t eth_mtu_size;
uint16_t ipv4_port;
uint16_t ipv6_port;
uint8_t control;
uint16_t ipv6_tcp_options;
uint8_t tcp_wsf;
uint8_t ipv6_tcp_wsf;
uint8_t ipv4_tos;
uint8_t ipv4_cache_id;
uint8_t ipv6_cache_id;
uint8_t ipv4_alt_cid_len;
uint8_t ipv4_alt_cid[11];
uint8_t ipv4_vid_len;
uint8_t ipv4_vid[11];
uint8_t ipv4_ttl;
uint16_t ipv6_flow_lbl;
uint8_t ipv6_traffic_class;
uint8_t ipv6_hop_limit;
uint32_t ipv6_nd_reach_time;
uint32_t ipv6_nd_rexmit_timer;
uint32_t ipv6_nd_stale_timeout;
uint8_t ipv6_dup_addr_detect_count;
uint32_t ipv6_gw_advrt_mtu;
uint16_t def_timeout;
uint8_t abort_timer;
uint16_t iscsi_options;
uint16_t iscsi_max_pdu_size;
uint16_t iscsi_first_burst_len;
uint16_t iscsi_max_outstnd_r2t;
uint16_t iscsi_max_burst_len;
uint8_t iscsi_name[224];
};
#define QL4_CHAP_MAX_NAME_LEN 256

View file

@ -551,6 +551,7 @@ struct addr_ctrl_blk {
#define IFCB_VER_MIN 0x01
#define IFCB_VER_MAX 0x02
uint8_t control; /* 01 */
#define CTRLOPT_NEW_CONN_DISABLE 0x0002
uint16_t fw_options; /* 02-03 */
#define FWOPT_HEARTBEAT_ENABLE 0x1000
@ -582,11 +583,40 @@ struct addr_ctrl_blk {
uint32_t shdwreg_addr_hi; /* 2C-2F */
uint16_t iscsi_opts; /* 30-31 */
#define ISCSIOPTS_HEADER_DIGEST_EN 0x2000
#define ISCSIOPTS_DATA_DIGEST_EN 0x1000
#define ISCSIOPTS_IMMEDIATE_DATA_EN 0x0800
#define ISCSIOPTS_INITIAL_R2T_EN 0x0400
#define ISCSIOPTS_DATA_SEQ_INORDER_EN 0x0200
#define ISCSIOPTS_DATA_PDU_INORDER_EN 0x0100
#define ISCSIOPTS_CHAP_AUTH_EN 0x0080
#define ISCSIOPTS_SNACK_EN 0x0040
#define ISCSIOPTS_DISCOVERY_LOGOUT_EN 0x0020
#define ISCSIOPTS_BIDI_CHAP_EN 0x0010
#define ISCSIOPTS_DISCOVERY_AUTH_EN 0x0008
#define ISCSIOPTS_STRICT_LOGIN_COMP_EN 0x0004
#define ISCSIOPTS_ERL 0x0003
uint16_t ipv4_tcp_opts; /* 32-33 */
#define TCPOPT_DELAYED_ACK_DISABLE 0x8000
#define TCPOPT_DHCP_ENABLE 0x0200
#define TCPOPT_DNS_SERVER_IP_EN 0x0100
#define TCPOPT_SLP_DA_INFO_EN 0x0080
#define TCPOPT_NAGLE_ALGO_DISABLE 0x0020
#define TCPOPT_WINDOW_SCALE_DISABLE 0x0010
#define TCPOPT_TIMER_SCALE 0x000E
#define TCPOPT_TIMESTAMP_ENABLE 0x0001
uint16_t ipv4_ip_opts; /* 34-35 */
#define IPOPT_IPV4_PROTOCOL_ENABLE 0x8000
#define IPOPT_IPV4_TOS_EN 0x4000
#define IPOPT_VLAN_TAGGING_ENABLE 0x2000
#define IPOPT_GRAT_ARP_EN 0x1000
#define IPOPT_ALT_CID_EN 0x0800
#define IPOPT_REQ_VID_EN 0x0400
#define IPOPT_USE_VID_EN 0x0200
#define IPOPT_LEARN_IQN_EN 0x0100
#define IPOPT_FRAGMENTATION_DISABLE 0x0010
#define IPOPT_IN_FORWARD_EN 0x0008
#define IPOPT_ARP_REDIRECT_EN 0x0004
uint16_t iscsi_max_pdu_size; /* 36-37 */
uint8_t ipv4_tos; /* 38 */
@ -637,15 +667,24 @@ struct addr_ctrl_blk {
uint32_t cookie; /* 200-203 */
uint16_t ipv6_port; /* 204-205 */
uint16_t ipv6_opts; /* 206-207 */
#define IPV6_OPT_IPV6_PROTOCOL_ENABLE 0x8000
#define IPV6_OPT_VLAN_TAGGING_ENABLE 0x2000
#define IPV6_OPT_IPV6_PROTOCOL_ENABLE 0x8000
#define IPV6_OPT_VLAN_TAGGING_ENABLE 0x2000
#define IPV6_OPT_GRAT_NEIGHBOR_ADV_EN 0x1000
#define IPV6_OPT_REDIRECT_EN 0x0004
uint16_t ipv6_addtl_opts; /* 208-209 */
#define IPV6_ADDOPT_IGNORE_ICMP_ECHO_REQ 0x0040
#define IPV6_ADDOPT_MLD_EN 0x0004
#define IPV6_ADDOPT_NEIGHBOR_DISCOVERY_ADDR_ENABLE 0x0002 /* Pri ACB
Only */
#define IPV6_ADDOPT_AUTOCONFIG_LINK_LOCAL_ADDR 0x0001
uint16_t ipv6_tcp_opts; /* 20A-20B */
#define IPV6_TCPOPT_DELAYED_ACK_DISABLE 0x8000
#define IPV6_TCPOPT_NAGLE_ALGO_DISABLE 0x0020
#define IPV6_TCPOPT_WINDOW_SCALE_DISABLE 0x0010
#define IPV6_TCPOPT_TIMER_SCALE 0x000E
#define IPV6_TCPOPT_TIMESTAMP_EN 0x0001
uint8_t ipv6_tcp_wsf; /* 20C */
uint16_t ipv6_flow_lbl; /* 20D-20F */
uint8_t ipv6_dflt_rtr_addr[16]; /* 210-21F */

View file

@ -276,6 +276,7 @@ int qla4xxx_get_acb(struct scsi_qla_host *ha, dma_addr_t acb_dma,
int qla4_84xx_config_acb(struct scsi_qla_host *ha, int acb_config);
int qla4_83xx_ms_mem_write_128b(struct scsi_qla_host *ha,
uint64_t addr, uint32_t *data, uint32_t count);
uint8_t qla4xxx_set_ipaddr_state(uint8_t fw_ipaddr_state);
extern int ql4xextended_error_logging;
extern int ql4xdontresethba;

View file

@ -606,6 +606,36 @@ static int qla4_83xx_loopback_in_progress(struct scsi_qla_host *ha)
return rval;
}
static void qla4xxx_update_ipaddr_state(struct scsi_qla_host *ha,
uint32_t ipaddr_idx,
uint32_t ipaddr_fw_state)
{
uint8_t ipaddr_state;
uint8_t ip_idx;
ip_idx = ipaddr_idx & 0xF;
ipaddr_state = qla4xxx_set_ipaddr_state((uint8_t)ipaddr_fw_state);
switch (ip_idx) {
case 0:
ha->ip_config.ipv4_addr_state = ipaddr_state;
break;
case 1:
ha->ip_config.ipv6_link_local_state = ipaddr_state;
break;
case 2:
ha->ip_config.ipv6_addr0_state = ipaddr_state;
break;
case 3:
ha->ip_config.ipv6_addr1_state = ipaddr_state;
break;
default:
ql4_printk(KERN_INFO, ha, "%s: Invalid IPADDR index %d\n",
__func__, ip_idx);
}
}
/**
* qla4xxx_isr_decode_mailbox - decodes mailbox status
* @ha: Pointer to host adapter structure.
@ -741,6 +771,8 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
"mbox_sts[3]=%04x\n", ha->host_no, mbox_sts[0],
mbox_sts[2], mbox_sts[3]);
qla4xxx_update_ipaddr_state(ha, mbox_sts[5],
mbox_sts[3]);
/* mbox_sts[2] = Old ACB state
* mbox_sts[3] = new ACB state */
if ((mbox_sts[3] == ACB_STATE_VALID) &&

View file

@ -418,6 +418,38 @@ qla4xxx_get_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
return QLA_SUCCESS;
}
uint8_t qla4xxx_set_ipaddr_state(uint8_t fw_ipaddr_state)
{
uint8_t ipaddr_state;
switch (fw_ipaddr_state) {
case IP_ADDRSTATE_UNCONFIGURED:
ipaddr_state = ISCSI_IPDDRESS_STATE_UNCONFIGURED;
break;
case IP_ADDRSTATE_INVALID:
ipaddr_state = ISCSI_IPDDRESS_STATE_INVALID;
break;
case IP_ADDRSTATE_ACQUIRING:
ipaddr_state = ISCSI_IPDDRESS_STATE_ACQUIRING;
break;
case IP_ADDRSTATE_TENTATIVE:
ipaddr_state = ISCSI_IPDDRESS_STATE_TENTATIVE;
break;
case IP_ADDRSTATE_DEPRICATED:
ipaddr_state = ISCSI_IPDDRESS_STATE_DEPRECATED;
break;
case IP_ADDRSTATE_PREFERRED:
ipaddr_state = ISCSI_IPDDRESS_STATE_VALID;
break;
case IP_ADDRSTATE_DISABLING:
ipaddr_state = ISCSI_IPDDRESS_STATE_DISABLING;
break;
default:
ipaddr_state = ISCSI_IPDDRESS_STATE_UNCONFIGURED;
}
return ipaddr_state;
}
static void
qla4xxx_update_local_ip(struct scsi_qla_host *ha,
struct addr_ctrl_blk *init_fw_cb)
@ -425,7 +457,7 @@ qla4xxx_update_local_ip(struct scsi_qla_host *ha,
ha->ip_config.tcp_options = le16_to_cpu(init_fw_cb->ipv4_tcp_opts);
ha->ip_config.ipv4_options = le16_to_cpu(init_fw_cb->ipv4_ip_opts);
ha->ip_config.ipv4_addr_state =
le16_to_cpu(init_fw_cb->ipv4_addr_state);
qla4xxx_set_ipaddr_state(init_fw_cb->ipv4_addr_state);
ha->ip_config.eth_mtu_size =
le16_to_cpu(init_fw_cb->eth_mtu_size);
ha->ip_config.ipv4_port = le16_to_cpu(init_fw_cb->ipv4_port);
@ -434,6 +466,8 @@ qla4xxx_update_local_ip(struct scsi_qla_host *ha,
ha->ip_config.ipv6_options = le16_to_cpu(init_fw_cb->ipv6_opts);
ha->ip_config.ipv6_addl_options =
le16_to_cpu(init_fw_cb->ipv6_addtl_opts);
ha->ip_config.ipv6_tcp_options =
le16_to_cpu(init_fw_cb->ipv6_tcp_opts);
}
/* Save IPv4 Address Info */
@ -448,17 +482,65 @@ qla4xxx_update_local_ip(struct scsi_qla_host *ha,
sizeof(init_fw_cb->ipv4_gw_addr)));
ha->ip_config.ipv4_vlan_tag = be16_to_cpu(init_fw_cb->ipv4_vlan_tag);
ha->ip_config.control = init_fw_cb->control;
ha->ip_config.tcp_wsf = init_fw_cb->ipv4_tcp_wsf;
ha->ip_config.ipv4_tos = init_fw_cb->ipv4_tos;
ha->ip_config.ipv4_cache_id = init_fw_cb->ipv4_cacheid;
ha->ip_config.ipv4_alt_cid_len = init_fw_cb->ipv4_dhcp_alt_cid_len;
memcpy(ha->ip_config.ipv4_alt_cid, init_fw_cb->ipv4_dhcp_alt_cid,
min(sizeof(ha->ip_config.ipv4_alt_cid),
sizeof(init_fw_cb->ipv4_dhcp_alt_cid)));
ha->ip_config.ipv4_vid_len = init_fw_cb->ipv4_dhcp_vid_len;
memcpy(ha->ip_config.ipv4_vid, init_fw_cb->ipv4_dhcp_vid,
min(sizeof(ha->ip_config.ipv4_vid),
sizeof(init_fw_cb->ipv4_dhcp_vid)));
ha->ip_config.ipv4_ttl = init_fw_cb->ipv4_ttl;
ha->ip_config.def_timeout = le16_to_cpu(init_fw_cb->def_timeout);
ha->ip_config.abort_timer = init_fw_cb->abort_timer;
ha->ip_config.iscsi_options = le16_to_cpu(init_fw_cb->iscsi_opts);
ha->ip_config.iscsi_max_pdu_size =
le16_to_cpu(init_fw_cb->iscsi_max_pdu_size);
ha->ip_config.iscsi_first_burst_len =
le16_to_cpu(init_fw_cb->iscsi_fburst_len);
ha->ip_config.iscsi_max_outstnd_r2t =
le16_to_cpu(init_fw_cb->iscsi_max_outstnd_r2t);
ha->ip_config.iscsi_max_burst_len =
le16_to_cpu(init_fw_cb->iscsi_max_burst_len);
memcpy(ha->ip_config.iscsi_name, init_fw_cb->iscsi_name,
min(sizeof(ha->ip_config.iscsi_name),
sizeof(init_fw_cb->iscsi_name)));
if (is_ipv6_enabled(ha)) {
/* Save IPv6 Address */
ha->ip_config.ipv6_link_local_state =
le16_to_cpu(init_fw_cb->ipv6_lnk_lcl_addr_state);
qla4xxx_set_ipaddr_state(init_fw_cb->ipv6_lnk_lcl_addr_state);
ha->ip_config.ipv6_addr0_state =
le16_to_cpu(init_fw_cb->ipv6_addr0_state);
qla4xxx_set_ipaddr_state(init_fw_cb->ipv6_addr0_state);
ha->ip_config.ipv6_addr1_state =
le16_to_cpu(init_fw_cb->ipv6_addr1_state);
ha->ip_config.ipv6_default_router_state =
le16_to_cpu(init_fw_cb->ipv6_dflt_rtr_state);
qla4xxx_set_ipaddr_state(init_fw_cb->ipv6_addr1_state);
switch (le16_to_cpu(init_fw_cb->ipv6_dflt_rtr_state)) {
case IPV6_RTRSTATE_UNKNOWN:
ha->ip_config.ipv6_default_router_state =
ISCSI_ROUTER_STATE_UNKNOWN;
break;
case IPV6_RTRSTATE_MANUAL:
ha->ip_config.ipv6_default_router_state =
ISCSI_ROUTER_STATE_MANUAL;
break;
case IPV6_RTRSTATE_ADVERTISED:
ha->ip_config.ipv6_default_router_state =
ISCSI_ROUTER_STATE_ADVERTISED;
break;
case IPV6_RTRSTATE_STALE:
ha->ip_config.ipv6_default_router_state =
ISCSI_ROUTER_STATE_STALE;
break;
default:
ha->ip_config.ipv6_default_router_state =
ISCSI_ROUTER_STATE_UNKNOWN;
}
ha->ip_config.ipv6_link_local_addr.in6_u.u6_addr8[0] = 0xFE;
ha->ip_config.ipv6_link_local_addr.in6_u.u6_addr8[1] = 0x80;
@ -479,6 +561,23 @@ qla4xxx_update_local_ip(struct scsi_qla_host *ha,
ha->ip_config.ipv6_vlan_tag =
be16_to_cpu(init_fw_cb->ipv6_vlan_tag);
ha->ip_config.ipv6_port = le16_to_cpu(init_fw_cb->ipv6_port);
ha->ip_config.ipv6_cache_id = init_fw_cb->ipv6_cache_id;
ha->ip_config.ipv6_flow_lbl =
le16_to_cpu(init_fw_cb->ipv6_flow_lbl);
ha->ip_config.ipv6_traffic_class =
init_fw_cb->ipv6_traffic_class;
ha->ip_config.ipv6_hop_limit = init_fw_cb->ipv6_hop_limit;
ha->ip_config.ipv6_nd_reach_time =
le32_to_cpu(init_fw_cb->ipv6_nd_reach_time);
ha->ip_config.ipv6_nd_rexmit_timer =
le32_to_cpu(init_fw_cb->ipv6_nd_rexmit_timer);
ha->ip_config.ipv6_nd_stale_timeout =
le32_to_cpu(init_fw_cb->ipv6_nd_stale_timeout);
ha->ip_config.ipv6_dup_addr_detect_count =
init_fw_cb->ipv6_dup_addr_detect_count;
ha->ip_config.ipv6_gw_advrt_mtu =
le32_to_cpu(init_fw_cb->ipv6_gw_advrt_mtu);
ha->ip_config.ipv6_tcp_wsf = init_fw_cb->ipv6_tcp_wsf;
}
}

File diff suppressed because it is too large Load diff