* [PATCH 0/5] qla4xxx: Proposal for iSCSI Network Configuration
@ 2011-04-22 18:07 vikas.chaudhary
2011-04-22 18:07 ` [PATCH 1/5] iscsi_transport: add support for set_net_config vikas.chaudhary
` (4 more replies)
0 siblings, 5 replies; 8+ messages in thread
From: vikas.chaudhary @ 2011-04-22 18:07 UTC (permalink / raw)
To: James.Bottomley, michaelc
Cc: linux-scsi, vikas.chaudhary, lalit.chandivade, ravi.anand
From: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
These patches are to configure network setting for iSCSI Adapter (qla4xxx)
that use private IP address. Patches are made on top of scsi-misc-2.6
git tree.
This patchset is revision of our RFC-v2 patchset which we posted earlier:
link: http://marc.info/?l=linux-scsi&m=130176955503554&w=2
Patches include following major changes from RFC-v2 patches.
- Cleanup white space errors.
- rename sysfs attr file from state to enabled as suggested by Mike Christie
Kernel Patches:
Lalit Chandivade (2):
iscsi_transport: add support for set_net_config
qla4xxx: add support for set_net_config
Vikas Chaudhary (3):
qla4xxx: Added new "struct ipaddress_config"
iscsi_transport: show network configuration in sysfs
qla4xxx: added support to show multiple iface in sysfs
iscsiadm patch:
Lalit Chandivade (1):
iscsiadm: Add netconfig support in iscsiadm and iscsid
Thanks,
Vikas.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/5] iscsi_transport: add support for set_net_config
2011-04-22 18:07 [PATCH 0/5] qla4xxx: Proposal for iSCSI Network Configuration vikas.chaudhary
@ 2011-04-22 18:07 ` vikas.chaudhary
2011-04-23 5:19 ` Mike Christie
2011-04-22 18:07 ` [PATCH 2/5] qla4xxx: " vikas.chaudhary
` (3 subsequent siblings)
4 siblings, 1 reply; 8+ messages in thread
From: vikas.chaudhary @ 2011-04-22 18:07 UTC (permalink / raw)
To: James.Bottomley, michaelc
Cc: linux-scsi, vikas.chaudhary, lalit.chandivade, ravi.anand,
Harish Zunjarrao
From: Lalit Chandivade <lalit.chandivade@qlogic.com>
Allows user space (iscsiadm) to send down network configuration parameters
for LLD to set private network configuration on the iSCSI adapters.
Signed-off-by: Lalit Chandivade <lalit.chandivade@qlogic.com>
Signed-off-by: Harish Zunjarrao <harish.zunjarrao@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Reviewed-by: Ravi Anand <ravi.anand@qlogic.com>
---
drivers/scsi/scsi_transport_iscsi.c | 27 ++++++++++++++++
include/scsi/iscsi_if.h | 58 +++++++++++++++++++++++++++++++++++
include/scsi/scsi_transport_iscsi.h | 1 +
3 files changed, 86 insertions(+), 0 deletions(-)
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 3fd16d7..7596234 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1558,6 +1558,30 @@ iscsi_set_path(struct iscsi_transport *transport, struct iscsi_uevent *ev)
}
static int
+iscsi_set_net_config(struct iscsi_transport *transport,
+ struct iscsi_uevent *ev)
+{
+ char *data = (char *)ev + sizeof(*ev);
+ struct Scsi_Host *shost;
+ int err;
+
+ if (!transport->set_net_config)
+ return -ENOSYS;
+
+ shost = scsi_host_lookup(ev->u.set_net_config.host_no);
+ if (!shost) {
+ printk(KERN_ERR "set_net_config could not find host no %u\n",
+ ev->u.set_net_config.host_no);
+ return -ENODEV;
+ }
+
+ err = transport->set_net_config(shost, data,
+ ev->u.set_net_config.count);
+ scsi_host_put(shost);
+ return err;
+}
+
+static int
iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
{
int err = 0;
@@ -1696,6 +1720,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
case ISCSI_UEVENT_PATH_UPDATE:
err = iscsi_set_path(transport, ev);
break;
+ case ISCSI_UEVENT_SET_NET_CONFIG:
+ err = iscsi_set_net_config(transport, ev);
+ break;
default:
err = -ENOSYS;
break;
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index ddb0456..449e55b 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -59,6 +59,7 @@ enum iscsi_uevent_e {
ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST = UEVENT_BASE + 19,
ISCSI_UEVENT_PATH_UPDATE = UEVENT_BASE + 20,
+ ISCSI_UEVENT_SET_NET_CONFIG = UEVENT_BASE + 21,
/* up events */
ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1,
@@ -172,6 +173,10 @@ struct iscsi_uevent {
struct msg_set_path {
uint32_t host_no;
} set_path;
+ struct msg_set_net_config {
+ uint32_t host_no;
+ uint32_t count;
+ } set_net_config;
} u;
union {
/* messages k -> u */
@@ -237,6 +242,59 @@ struct iscsi_path {
uint16_t pmtu;
} __attribute__ ((aligned (sizeof(uint64_t))));
+#define ISCSI_FALSE 0
+#define ISCSI_TRUE 1
+
+/* ipv4 bootproto */
+#define ISCSI_BOOTPROTO_STATIC 0x01
+#define ISCSI_BOOTPROTO_DHCP 0x02
+
+/* ipv6 addr autoconfig type */
+#define ISCSI_IPV6_AUTOCFG_DISABLE 0x01
+#define ISCSI_IPV6_AUTOCFG_ND_ENABLE 0x02
+#define ISCSI_IPV6_AUTOCFG_DHCPV6_ENABLE 0x03
+
+/* ipv6 link local addr type */
+#define ISCSI_IPV6_LINKLOCAL_AUTOCFG_ENABLE 0x01
+#define ISCSI_IPV6_LINKLOCAL_AUTOCFG_DISABLE 0x02
+
+/* ipv6 router addr type */
+#define ISCSI_IPV6_ROUTER_AUTOCFG_ENABLE 0x01
+#define ISCSI_IPV6_ROUTER_AUTOCFG_DISABLE 0x02
+
+/* iSCSI network params */
+enum iscsi_net_param_type {
+ ISCSI_NET_PARAM_IPV4_ADDR = 1,
+ ISCSI_NET_PARAM_IPV4_SUBNET = 2,
+ ISCSI_NET_PARAM_IPV4_GW = 3,
+ ISCSI_NET_PARAM_IPV4_BOOTPROTO = 4,
+ ISCSI_NET_PARAM_MAC = 5,
+ ISCSI_NET_PARAM_IPV6_LINKLOCAL = 6,
+ ISCSI_NET_PARAM_IPV6_ADDR = 7,
+ ISCSI_NET_PARAM_IPV6_ROUTER = 8,
+ ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG = 9,
+ ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG = 10,
+ ISCSI_NET_PARAM_IPV6_ROUTER_AUTOCFG = 11,
+ ISCSI_NET_PARAM_IFACE_ENABLED = 12,
+ ISCSI_NET_PARAM_VLAN = 13,
+};
+
+/* 20 param per iface * 10 iface per port = 200 params */
+#define ISCSI_MAX_IFACE_PER_HW 10
+#define ISCSI_MAX_PARAM_PER_IFACE 20
+#define ISCSI_MAX_NET_PARAMS (ISCSI_MAX_IFACE_PER_HW * \
+ ISCSI_MAX_PARAM_PER_IFACE)
+
+#define IFACE_TYPE_IPV4 0x01
+#define IFACE_TYPE_IPV6 0x02
+struct iscsi_net_param {
+ uint32_t param_type; /* enum iscsi_net_param */
+ uint32_t iface_type; /* IPv4 or IPv6 */
+ uint32_t iface_num; /* iface number, 0 - n */
+ uint32_t length; /* Actual length of the param */
+ uint8_t value[0]; /* length sized value follows */
+} __packed;
+
/*
* Common error codes
*/
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index bf8f529..45b9df9 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -137,6 +137,7 @@ struct iscsi_transport {
int (*tgt_dscvr) (struct Scsi_Host *shost, enum iscsi_tgt_dscvr type,
uint32_t enable, struct sockaddr *dst_addr);
int (*set_path) (struct Scsi_Host *shost, struct iscsi_path *params);
+ int (*set_net_config) (struct Scsi_Host *shost, char *data, int count);
};
/*
--
1.7.3.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/5] qla4xxx: add support for set_net_config
2011-04-22 18:07 [PATCH 0/5] qla4xxx: Proposal for iSCSI Network Configuration vikas.chaudhary
2011-04-22 18:07 ` [PATCH 1/5] iscsi_transport: add support for set_net_config vikas.chaudhary
@ 2011-04-22 18:07 ` vikas.chaudhary
2011-04-22 18:07 ` [PATCH 3/5] qla4xxx: Added new "struct ipaddress_config" vikas.chaudhary
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: vikas.chaudhary @ 2011-04-22 18:07 UTC (permalink / raw)
To: James.Bottomley, michaelc
Cc: linux-scsi, vikas.chaudhary, lalit.chandivade, ravi.anand,
Harish Zunjarrao
From: Lalit Chandivade <lalit.chandivade@qlogic.com>
Allows user space (iscsiadm) to send down network configuration parameters
for LLD to set private network configuration on the iSCSI adapters.
Signed-off-by: Lalit Chandivade <lalit.chandivade@qlogic.com>
Signed-off-by: Harish Zunjarrao <harish.zunjarrao@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Reviewed-by: Ravi Anand <ravi.anand@qlogic.com>
---
drivers/scsi/qla4xxx/ql4_fw.h | 77 ++++++++++
drivers/scsi/qla4xxx/ql4_glbl.h | 20 +++-
drivers/scsi/qla4xxx/ql4_mbx.c | 119 +++++++++++++++-
drivers/scsi/qla4xxx/ql4_os.c | 302 +++++++++++++++++++++++++++++++++++++++
4 files changed, 514 insertions(+), 4 deletions(-)
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
index 31e2bf9..d05e8be 100644
--- a/drivers/scsi/qla4xxx/ql4_fw.h
+++ b/drivers/scsi/qla4xxx/ql4_fw.h
@@ -434,6 +434,14 @@ struct qla_flt_region {
#define ACB_STATE_VALID 0x05
#define ACB_STATE_DISABLING 0x06
+/* FLASH offsets */
+#define FLASH_SEGMENT_IFCB 0x04000000
+
+#define FLASH_OPT_RMW_HOLD 0
+#define FLASH_OPT_RMW_INIT 1
+#define FLASH_OPT_COMMIT 2
+#define FLASH_OPT_RMW_COMMIT 3
+
/*************************************************************************/
/* Host Adapter Initialization Control Block (from host) */
@@ -473,6 +481,7 @@ struct addr_ctrl_blk {
uint16_t iscsi_opts; /* 30-31 */
uint16_t ipv4_tcp_opts; /* 32-33 */
+#define TCPOPT_DHCP_ENABLE 0x0200
uint16_t ipv4_ip_opts; /* 34-35 */
#define IPOPT_IPv4_PROTOCOL_ENABLE 0x8000
@@ -574,6 +583,74 @@ struct init_fw_ctrl_blk {
/* struct addr_ctrl_blk sec;*/
};
+struct addr_ctrl_blk_def {
+ uint8_t reserved1[1]; /* 00 */
+ uint8_t control; /* 01 */
+ uint8_t reserved2[11]; /* 02-0C */
+ uint8_t inst_num; /* 0D */
+ uint8_t reserved3[34]; /* 0E-2F */
+ uint16_t iscsi_opts; /* 30-31 */
+ uint16_t ipv4_tcp_opts; /* 32-33 */
+ uint16_t ipv4_ip_opts; /* 34-35 */
+ uint16_t iscsi_max_pdu_size; /* 36-37 */
+ uint8_t ipv4_tos; /* 38 */
+ uint8_t ipv4_ttl; /* 39 */
+ uint8_t reserved4[2]; /* 3A-3B */
+ uint16_t def_timeout; /* 3C-3D */
+ uint16_t iscsi_fburst_len; /* 3E-3F */
+ uint8_t reserved5[4]; /* 40-43 */
+ uint16_t iscsi_max_outstnd_r2t; /* 44-45 */
+ uint8_t reserved6[2]; /* 46-47 */
+ uint16_t ipv4_port; /* 48-49 */
+ uint16_t iscsi_max_burst_len; /* 4A-4B */
+ uint8_t reserved7[4]; /* 4C-4F */
+ uint8_t ipv4_addr[4]; /* 50-53 */
+ uint16_t ipv4_vlan_tag; /* 54-55 */
+ uint8_t ipv4_addr_state; /* 56 */
+ uint8_t ipv4_cacheid; /* 57 */
+ uint8_t reserved8[8]; /* 58-5F */
+ uint8_t ipv4_subnet[4]; /* 60-63 */
+ uint8_t reserved9[12]; /* 64-6F */
+ uint8_t ipv4_gw_addr[4]; /* 70-73 */
+ uint8_t reserved10[84]; /* 74-C7 */
+ uint8_t abort_timer; /* C8 */
+ uint8_t ipv4_tcp_wsf; /* C9 */
+ uint8_t reserved11[10]; /* CA-D3 */
+ uint8_t ipv4_dhcp_vid_len; /* D4 */
+ uint8_t ipv4_dhcp_vid[11]; /* D5-DF */
+ uint8_t reserved12[20]; /* E0-F3 */
+ uint8_t ipv4_dhcp_alt_cid_len; /* F4 */
+ uint8_t ipv4_dhcp_alt_cid[11]; /* F5-FF */
+ uint8_t iscsi_name[224]; /* 100-1DF */
+ uint8_t reserved13[32]; /* 1E0-1FF */
+ uint32_t cookie; /* 200-203 */
+ uint16_t ipv6_port; /* 204-205 */
+ uint16_t ipv6_opts; /* 206-207 */
+ uint16_t ipv6_addtl_opts; /* 208-209 */
+ uint16_t ipv6_tcp_opts; /* 20A-20B */
+ uint8_t ipv6_tcp_wsf; /* 20C */
+ uint16_t ipv6_flow_lbl; /* 20D-20F */
+ uint8_t ipv6_dflt_rtr_addr[16]; /* 210-21F */
+ uint16_t ipv6_vlan_tag; /* 220-221 */
+ uint8_t ipv6_lnk_lcl_addr_state; /* 222 */
+ uint8_t ipv6_addr0_state; /* 223 */
+ uint8_t ipv6_addr1_state; /* 224 */
+ uint8_t ipv6_dflt_rtr_state; /* 225 */
+ uint8_t ipv6_traffic_class; /* 226 */
+ uint8_t ipv6_hop_limit; /* 227 */
+ uint8_t ipv6_if_id[8]; /* 228-22F */
+ uint8_t ipv6_addr0[16]; /* 230-23F */
+ uint8_t ipv6_addr1[16]; /* 240-24F */
+ uint32_t ipv6_nd_reach_time; /* 250-253 */
+ uint32_t ipv6_nd_rexmit_timer; /* 254-257 */
+ uint32_t ipv6_nd_stale_timeout; /* 258-25B */
+ uint8_t ipv6_dup_addr_detect_count; /* 25C */
+ uint8_t ipv6_cache_id; /* 25D */
+ uint8_t reserved14[18]; /* 25E-26F */
+ uint32_t ipv6_gw_advrt_mtu; /* 270-273 */
+ uint8_t reserved15[140]; /* 274-2FF */
+};
+
/*************************************************************************/
struct dev_db_entry {
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index cc53e3f..9c5c5e3 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -52,7 +52,17 @@ int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha,
int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index,
dma_addr_t fw_ddb_entry_dma);
-
+uint8_t qla4xxx_get_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
+ uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma);
+int qla4xxx_conn_close_sess_logout(struct scsi_qla_host *ha,
+ uint16_t fw_ddb_index,
+ uint16_t connection_id,
+ uint16_t option);
+int qla4xxx_disable_acb(struct scsi_qla_host *ha);
+int qla4xxx_set_acb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
+ uint32_t *mbox_sts, dma_addr_t acb_dma);
+int qla4xxx_get_acb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
+ uint32_t *mbox_sts, dma_addr_t acb_dma);
void qla4xxx_mark_device_missing(struct scsi_qla_host *ha,
struct ddb_entry *ddb_entry);
u16 rd_nvram_word(struct scsi_qla_host *ha, int offset);
@@ -75,7 +85,8 @@ void qla4xxx_dump_buffer(void *b, uint32_t size);
int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha,
struct ddb_entry *ddb_entry, int lun, uint16_t mrkr_mod);
int qla4_is_relogin_allowed(struct scsi_qla_host *ha, uint32_t conn_err);
-
+int qla4xxx_set_flash(struct scsi_qla_host *ha, dma_addr_t dma_addr,
+ uint32_t offset, uint32_t length, uint32_t options);
int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
uint8_t outCount, uint32_t *mbx_cmd, uint32_t *mbx_sts);
@@ -95,6 +106,11 @@ void qla4xxx_wake_dpc(struct scsi_qla_host *ha);
void qla4xxx_get_conn_event_log(struct scsi_qla_host *ha);
void qla4xxx_mailbox_premature_completion(struct scsi_qla_host *ha);
void qla4xxx_dump_registers(struct scsi_qla_host *ha);
+uint8_t qla4xxx_update_local_ifcb(struct scsi_qla_host *ha,
+ uint32_t *mbox_cmd,
+ uint32_t *mbox_sts,
+ struct addr_ctrl_blk *init_fw_cb,
+ dma_addr_t init_fw_cb_dma);
void qla4_8xxx_pci_config(struct scsi_qla_host *);
int qla4_8xxx_iospace_config(struct scsi_qla_host *ha);
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index f9d81c8..743290e 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -317,7 +317,7 @@ qla4xxx_set_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
return QLA_SUCCESS;
}
-static uint8_t
+uint8_t
qla4xxx_get_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma)
{
@@ -377,7 +377,7 @@ qla4xxx_update_local_ip(struct scsi_qla_host *ha,
}
}
-static uint8_t
+uint8_t
qla4xxx_update_local_ifcb(struct scsi_qla_host *ha,
uint32_t *mbox_cmd,
uint32_t *mbox_sts,
@@ -1194,3 +1194,118 @@ exit_send_tgts_no_free:
return ret_val;
}
+int qla4xxx_set_flash(struct scsi_qla_host *ha, dma_addr_t dma_addr,
+ uint32_t offset, uint32_t length, uint32_t options)
+{
+ uint32_t mbox_cmd[MBOX_REG_COUNT];
+ uint32_t mbox_sts[MBOX_REG_COUNT];
+ int status = QLA_SUCCESS;
+
+ memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+ memset(&mbox_sts, 0, sizeof(mbox_sts));
+
+ mbox_cmd[0] = MBOX_CMD_WRITE_FLASH;
+ mbox_cmd[1] = LSDW(dma_addr);
+ mbox_cmd[2] = MSDW(dma_addr);
+ mbox_cmd[3] = offset;
+ mbox_cmd[4] = length;
+ mbox_cmd[5] = options;
+
+ status = qla4xxx_mailbox_command(ha, 6, 2, &mbox_cmd[0], &mbox_sts[0]);
+ if (status != QLA_SUCCESS) {
+ DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_WRITE_FLASH "
+ "failed w/ status %04X, mbx1 %04X\n",
+ __func__, mbox_sts[0], mbox_sts[1]));
+ }
+ return status;
+}
+
+int qla4xxx_conn_close_sess_logout(struct scsi_qla_host *ha,
+ uint16_t fw_ddb_index,
+ uint16_t connection_id,
+ uint16_t option)
+{
+ uint32_t mbox_cmd[MBOX_REG_COUNT];
+ uint32_t mbox_sts[MBOX_REG_COUNT];
+ int status = QLA_SUCCESS;
+
+ memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+ memset(&mbox_sts, 0, sizeof(mbox_sts));
+
+ mbox_cmd[0] = MBOX_CMD_CONN_CLOSE_SESS_LOGOUT;
+ mbox_cmd[1] = fw_ddb_index;
+ mbox_cmd[2] = connection_id;
+ mbox_cmd[3] = option;
+
+ status = qla4xxx_mailbox_command(ha, 4, 2, &mbox_cmd[0], &mbox_sts[0]);
+ if (status != QLA_SUCCESS) {
+ DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_CONN_CLOSE "
+ "option %04x failed w/ status %04X %04X\n",
+ __func__, option, mbox_sts[0], mbox_sts[1]));
+ }
+ return status;
+}
+
+int qla4xxx_disable_acb(struct scsi_qla_host *ha)
+{
+ uint32_t mbox_cmd[MBOX_REG_COUNT];
+ uint32_t mbox_sts[MBOX_REG_COUNT];
+ int status = QLA_SUCCESS;
+
+ memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+ memset(&mbox_sts, 0, sizeof(mbox_sts));
+
+ mbox_cmd[0] = MBOX_CMD_DISABLE_ACB;
+
+ status = qla4xxx_mailbox_command(ha, 8, 5, &mbox_cmd[0], &mbox_sts[0]);
+ if (status != QLA_SUCCESS) {
+ DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_DISABLE_ACB "
+ "failed w/ status %04X %04X %04X", __func__,
+ mbox_sts[0], mbox_sts[1], mbox_sts[2]));
+ }
+ return status;
+}
+
+int qla4xxx_get_acb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
+ uint32_t *mbox_sts, dma_addr_t acb_dma)
+{
+ int status = QLA_SUCCESS;
+
+ memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);
+ memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);
+ mbox_cmd[0] = MBOX_CMD_GET_ACB;
+ mbox_cmd[1] = 0; /* Primary ACB */
+ mbox_cmd[2] = LSDW(acb_dma);
+ mbox_cmd[3] = MSDW(acb_dma);
+ mbox_cmd[4] = sizeof(struct addr_ctrl_blk);
+
+ status = qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]);
+ if (status != QLA_SUCCESS) {
+ DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_GET_ACB "
+ "failed w/ status %04X\n", __func__,
+ mbox_sts[0]));
+ }
+ return status;
+}
+
+int qla4xxx_set_acb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
+ uint32_t *mbox_sts, dma_addr_t acb_dma)
+{
+ int status = QLA_SUCCESS;
+
+ memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);
+ memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);
+ mbox_cmd[0] = MBOX_CMD_SET_ACB;
+ mbox_cmd[1] = 0; /* Primary ACB */
+ mbox_cmd[2] = LSDW(acb_dma);
+ mbox_cmd[3] = MSDW(acb_dma);
+ mbox_cmd[4] = sizeof(struct addr_ctrl_blk);
+
+ status = qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]);
+ if (status != QLA_SUCCESS) {
+ DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_SET_ACB "
+ "failed w/ status %04X\n", __func__,
+ mbox_sts[0]));
+ }
+ return status;
+}
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 230ba09..e9b669d 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -80,6 +80,8 @@ static int qla4xxx_sess_get_param(struct iscsi_cls_session *sess,
enum iscsi_param param, char *buf);
static int qla4xxx_host_get_param(struct Scsi_Host *shost,
enum iscsi_host_param param, char *buf);
+static int qla4xxx_set_net_config(struct Scsi_Host *shost, char *data,
+ int count);
static void qla4xxx_recovery_timedout(struct iscsi_cls_session *session);
static enum blk_eh_timer_return qla4xxx_eh_cmd_timed_out(struct scsi_cmnd *sc);
@@ -141,6 +143,7 @@ static struct iscsi_transport qla4xxx_iscsi_transport = {
.get_conn_param = qla4xxx_conn_get_param,
.get_session_param = qla4xxx_sess_get_param,
.get_host_param = qla4xxx_host_get_param,
+ .set_net_config = qla4xxx_set_net_config,
.session_recovery_timedout = qla4xxx_recovery_timedout,
};
@@ -201,6 +204,305 @@ static int qla4xxx_host_get_param(struct Scsi_Host *shost,
return len;
}
+static inline void qla4xxx_set_ipv6(struct scsi_qla_host *ha,
+ struct iscsi_net_param *net_param,
+ struct addr_ctrl_blk *init_fw_cb)
+{
+ /*
+ * iface_num 0 is valid for IPv6 Addr, linklocal, router, autocfg.
+ * iface_num 1 is valid only for IPv6 Addr.
+ */
+ switch (net_param->param_type) {
+ case ISCSI_NET_PARAM_IPV6_ADDR:
+ if (net_param->iface_num & 0x1)
+ /* IPv6 Addr 1 */
+ memcpy(init_fw_cb->ipv6_addr1, net_param->value,
+ sizeof(init_fw_cb->ipv6_addr1));
+ else
+ /* IPv6 Addr 0 */
+ memcpy(init_fw_cb->ipv6_addr0, net_param->value,
+ sizeof(init_fw_cb->ipv6_addr0));
+ break;
+ case ISCSI_NET_PARAM_IPV6_LINKLOCAL:
+ if (net_param->iface_num & 0x1)
+ break;
+ memcpy(init_fw_cb->ipv6_if_id, &net_param->value[8],
+ sizeof(init_fw_cb->ipv6_if_id));
+ break;
+ case ISCSI_NET_PARAM_IPV6_ROUTER:
+ if (net_param->iface_num & 0x1)
+ break;
+ memcpy(init_fw_cb->ipv6_dflt_rtr_addr, net_param->value,
+ sizeof(init_fw_cb->ipv6_dflt_rtr_addr));
+ break;
+ case ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG:
+ /* Autocfg applies to even interface */
+ if (net_param->iface_num & 0x1)
+ break;
+
+ if (net_param->value[0] == ISCSI_IPV6_AUTOCFG_DISABLE)
+ init_fw_cb->ipv6_addtl_opts &=
+ cpu_to_le16(
+ ~IPV6_ADDOPT_NEIGHBOR_DISCOVERY_ADDR_ENABLE);
+ else if (net_param->value[0] == ISCSI_IPV6_AUTOCFG_ND_ENABLE)
+ init_fw_cb->ipv6_addtl_opts |=
+ cpu_to_le16(
+ IPV6_ADDOPT_NEIGHBOR_DISCOVERY_ADDR_ENABLE);
+ else
+ ql4_printk(KERN_ERR, ha, "Invalid autocfg setting for "
+ "IPv6 addr\n");
+ break;
+ case ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG:
+ /* Autocfg applies to even interface */
+ if (net_param->iface_num & 0x1)
+ break;
+
+ if (net_param->value[0] == ISCSI_IPV6_LINKLOCAL_AUTOCFG_ENABLE)
+ init_fw_cb->ipv6_addtl_opts |= cpu_to_le16(
+ IPV6_ADDOPT_AUTOCONFIG_LINK_LOCAL_ADDR);
+ else if (net_param->value[0] ==
+ ISCSI_IPV6_LINKLOCAL_AUTOCFG_DISABLE)
+ init_fw_cb->ipv6_addtl_opts &= cpu_to_le16(
+ ~IPV6_ADDOPT_AUTOCONFIG_LINK_LOCAL_ADDR);
+ else
+ ql4_printk(KERN_ERR, ha, "Invalid autocfg setting for "
+ "IPv6 linklocal addr\n");
+ break;
+ case ISCSI_NET_PARAM_IPV6_ROUTER_AUTOCFG:
+ /* Autocfg applies to even interface */
+ if (net_param->iface_num & 0x1)
+ break;
+
+ if (net_param->value[0] == ISCSI_IPV6_ROUTER_AUTOCFG_ENABLE)
+ memset(init_fw_cb->ipv6_dflt_rtr_addr, 0,
+ sizeof(init_fw_cb->ipv6_dflt_rtr_addr));
+ break;
+ case ISCSI_NET_PARAM_IFACE_ENABLED:
+ if (net_param->value[0] == ISCSI_TRUE)
+ init_fw_cb->ipv6_opts |=
+ cpu_to_le16(IPV6_OPT_IPV6_PROTOCOL_ENABLE);
+ else
+ init_fw_cb->ipv6_opts &=
+ cpu_to_le16(~IPV6_OPT_IPV6_PROTOCOL_ENABLE &
+ 0xFFFF);
+ break;
+ case ISCSI_NET_PARAM_VLAN:
+ if (net_param->length != sizeof(init_fw_cb->ipv6_vlan_tag))
+ break;
+ init_fw_cb->ipv6_vlan_tag = *(uint16_t *)net_param->value;
+ break;
+ default:
+ ql4_printk(KERN_ERR, ha, "Unknown IPv6 param = %d\n",
+ net_param->param_type);
+ break;
+ }
+}
+
+static inline void qla4xxx_set_ipv4(struct scsi_qla_host *ha,
+ struct iscsi_net_param *net_param,
+ struct addr_ctrl_blk *init_fw_cb)
+{
+ switch (net_param->param_type) {
+ case ISCSI_NET_PARAM_IPV4_ADDR:
+ memcpy(init_fw_cb->ipv4_addr, net_param->value,
+ sizeof(init_fw_cb->ipv4_addr));
+ break;
+ case ISCSI_NET_PARAM_IPV4_SUBNET:
+ memcpy(init_fw_cb->ipv4_subnet, net_param->value,
+ sizeof(init_fw_cb->ipv4_subnet));
+ break;
+ case ISCSI_NET_PARAM_IPV4_GW:
+ memcpy(init_fw_cb->ipv4_gw_addr, net_param->value,
+ sizeof(init_fw_cb->ipv4_gw_addr));
+ break;
+ case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
+ if (net_param->value[0] == ISCSI_BOOTPROTO_DHCP)
+ init_fw_cb->ipv4_tcp_opts |=
+ cpu_to_le16(TCPOPT_DHCP_ENABLE);
+ else if (net_param->value[0] == ISCSI_BOOTPROTO_STATIC)
+ init_fw_cb->ipv4_tcp_opts &=
+ cpu_to_le16(~TCPOPT_DHCP_ENABLE);
+ else
+ ql4_printk(KERN_ERR, ha, "Invalid IPv4 bootproto\n");
+ break;
+ case ISCSI_NET_PARAM_IFACE_ENABLED:
+ if (net_param->value[0] == ISCSI_TRUE)
+ init_fw_cb->ipv4_ip_opts |=
+ cpu_to_le16(IPOPT_IPv4_PROTOCOL_ENABLE);
+ else
+ init_fw_cb->ipv4_ip_opts &=
+ cpu_to_le16(~IPOPT_IPv4_PROTOCOL_ENABLE &
+ 0xFFFF);
+ break;
+ case ISCSI_NET_PARAM_VLAN:
+ if (net_param->length != sizeof(init_fw_cb->ipv4_vlan_tag))
+ break;
+ init_fw_cb->ipv4_vlan_tag = *(uint16_t *)net_param->value;
+ break;
+ default:
+ ql4_printk(KERN_ERR, ha, "Unknown IPv4 param = %d\n",
+ net_param->param_type);
+ break;
+ }
+}
+
+static void
+qla4xxx_initcb_to_acb(struct addr_ctrl_blk *init_fw_cb)
+{
+ struct addr_ctrl_blk_def *acb;
+ acb = (struct addr_ctrl_blk_def *)init_fw_cb;
+ memset(acb->reserved1, 0, sizeof(acb->reserved1));
+ memset(acb->reserved2, 0, sizeof(acb->reserved2));
+ memset(acb->reserved3, 0, sizeof(acb->reserved3));
+ memset(acb->reserved4, 0, sizeof(acb->reserved4));
+ memset(acb->reserved5, 0, sizeof(acb->reserved5));
+ memset(acb->reserved6, 0, sizeof(acb->reserved6));
+ memset(acb->reserved7, 0, sizeof(acb->reserved7));
+ memset(acb->reserved8, 0, sizeof(acb->reserved8));
+ memset(acb->reserved9, 0, sizeof(acb->reserved9));
+ memset(acb->reserved10, 0, sizeof(acb->reserved10));
+ memset(acb->reserved11, 0, sizeof(acb->reserved11));
+ memset(acb->reserved12, 0, sizeof(acb->reserved12));
+ memset(acb->reserved13, 0, sizeof(acb->reserved13));
+ memset(acb->reserved14, 0, sizeof(acb->reserved14));
+ memset(acb->reserved15, 0, sizeof(acb->reserved15));
+}
+
+static int
+qla4xxx_set_net_config(struct Scsi_Host *shost, char *data, int count)
+{
+ struct scsi_qla_host *ha = to_qla_host(shost);
+ int rval = 0;
+ struct iscsi_net_param *net_param = NULL;
+ struct addr_ctrl_blk *init_fw_cb = NULL;
+ dma_addr_t init_fw_cb_dma;
+
+ struct addr_ctrl_blk *acb = NULL;
+ dma_addr_t acb_dma;
+
+ uint32_t mbox_cmd[MBOX_REG_COUNT];
+ uint32_t mbox_sts[MBOX_REG_COUNT];
+ uint32_t total_param_count;
+ uint32_t length;
+
+ init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,
+ sizeof(struct addr_ctrl_blk),
+ &init_fw_cb_dma, GFP_KERNEL);
+ if (!init_fw_cb) {
+ ql4_printk(KERN_ERR, ha, "%s: Unable to alloc init_cb\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ acb = dma_alloc_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk),
+ &acb_dma, GFP_KERNEL);
+ if (!acb) {
+ ql4_printk(KERN_ERR, ha, "%s: Unable to alloc acb\n",
+ __func__);
+ rval = -ENOMEM;
+ goto exit_init_fw_cb;
+ }
+ memset(init_fw_cb, 0, sizeof(struct addr_ctrl_blk));
+ memset(acb, 0, sizeof(struct addr_ctrl_blk));
+ memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+ memset(&mbox_sts, 0, sizeof(mbox_sts));
+
+ if (qla4xxx_get_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma)) {
+ ql4_printk(KERN_ERR, ha, "%s: get ifcb failed\n", __func__);
+ rval = -EIO;
+ goto exit_init_fw_cb;
+ }
+
+ total_param_count = count;
+ net_param = (struct iscsi_net_param *)data;
+
+ for ( ; total_param_count != 0; total_param_count--) {
+ length = net_param->length;
+
+ switch (net_param->iface_type) {
+ case IFACE_TYPE_IPV4:
+ switch (net_param->iface_num) {
+ case 0:
+ qla4xxx_set_ipv4(ha, net_param, init_fw_cb);
+ break;
+ default:
+ /* Cannot have more than one IPv4 interface */
+ ql4_printk(KERN_ERR, ha, "Invalid IPv4 iface "
+ "number = %d\n",
+ net_param->iface_num);
+ break;
+ }
+ break;
+ case IFACE_TYPE_IPV6:
+ switch (net_param->iface_num) {
+ case 0:
+ case 1:
+ qla4xxx_set_ipv6(ha, net_param, init_fw_cb);
+ break;
+ default:
+ /* Cannot have more than two IPv6 interface */
+ ql4_printk(KERN_ERR, ha, "Invalid IPv6 iface "
+ "number = %d\n",
+ net_param->iface_num);
+ break;
+ }
+ break;
+ default:
+ ql4_printk(KERN_ERR, ha, "%s: Invalid iface type\n",
+ __func__);
+ break;
+ }
+
+ net_param = (struct iscsi_net_param *)((uint8_t *)net_param +
+ sizeof(struct iscsi_net_param) + length);
+ }
+
+ init_fw_cb->cookie = cpu_to_le32(0x11BEAD5A);
+
+ rval = qla4xxx_set_flash(ha, init_fw_cb_dma, FLASH_SEGMENT_IFCB,
+ sizeof(struct addr_ctrl_blk),
+ FLASH_OPT_RMW_COMMIT);
+ if (rval != QLA_SUCCESS) {
+ ql4_printk(KERN_ERR, ha, "%s: set flash mbx failed\n",
+ __func__);
+ rval = -EIO;
+ goto exit_init_fw_cb;
+ }
+
+ qla4xxx_disable_acb(ha);
+
+ /* Get ACB to check the state of IP address */
+ rval = qla4xxx_get_acb(ha, &mbox_cmd[0], &mbox_sts[0], acb_dma);
+ if (rval != QLA_SUCCESS) {
+ ql4_printk(KERN_ERR, ha, "%s: get acb mbx failed\n",
+ __func__);
+ rval = -EIO;
+ goto exit_acb;
+ }
+
+ qla4xxx_initcb_to_acb(init_fw_cb);
+ rval = qla4xxx_set_acb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma);
+ if (rval != QLA_SUCCESS) {
+ ql4_printk(KERN_ERR, ha, "%s: set acb mbx failed\n",
+ __func__);
+ rval = -EIO;
+ goto exit_acb;
+ }
+
+ memset(init_fw_cb, 0, sizeof(struct addr_ctrl_blk));
+ qla4xxx_update_local_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb,
+ init_fw_cb_dma);
+
+exit_acb:
+ dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk),
+ acb, acb_dma);
+exit_init_fw_cb:
+ dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk),
+ init_fw_cb, init_fw_cb_dma);
+
+ return rval;
+}
+
static int qla4xxx_sess_get_param(struct iscsi_cls_session *sess,
enum iscsi_param param, char *buf)
{
--
1.7.3.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/5] qla4xxx: Added new "struct ipaddress_config"
2011-04-22 18:07 [PATCH 0/5] qla4xxx: Proposal for iSCSI Network Configuration vikas.chaudhary
2011-04-22 18:07 ` [PATCH 1/5] iscsi_transport: add support for set_net_config vikas.chaudhary
2011-04-22 18:07 ` [PATCH 2/5] qla4xxx: " vikas.chaudhary
@ 2011-04-22 18:07 ` vikas.chaudhary
2011-04-22 18:07 ` [PATCH 4/5] iscsi_transport: show network configuration in sysfs vikas.chaudhary
2011-04-22 18:07 ` [PATCH 5/5] qla4xxx: added support to show multiple iface " vikas.chaudhary
4 siblings, 0 replies; 8+ messages in thread
From: vikas.chaudhary @ 2011-04-22 18:07 UTC (permalink / raw)
To: James.Bottomley, michaelc
Cc: linux-scsi, vikas.chaudhary, lalit.chandivade, ravi.anand
From: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
- Move all ipaddress related param to "struct ipaddress_config"
from "struct scsi_qla_host"
- update function - qla4xxx_update_local_ip()
- Rename IPOPT_IPv4_PROTOCOL_ENABLE to IPOPT_IPV4_PROTOCOL_ENABLE
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
---
drivers/scsi/qla4xxx/ql4_def.h | 47 ++++++++++++----------
drivers/scsi/qla4xxx/ql4_fw.h | 2 +-
drivers/scsi/qla4xxx/ql4_init.c | 53 +++++++++++++++----------
drivers/scsi/qla4xxx/ql4_mbx.c | 81 ++++++++++++++++++++++-----------------
drivers/scsi/qla4xxx/ql4_os.c | 8 +--
5 files changed, 107 insertions(+), 84 deletions(-)
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index 4757878..bce5c89 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -357,6 +357,28 @@ struct isp_operations {
int (*get_sys_info) (struct scsi_qla_host *);
};
+/*qla4xxx ipaddress configuration details */
+struct ipaddress_config {
+ uint16_t ipv4_options;
+ uint16_t tcp_options;
+ uint16_t ipv4_vlan_tag;
+ uint8_t ipv4_addr_state;
+ uint8_t ip_address[IP_ADDR_LEN];
+ uint8_t subnet_mask[IP_ADDR_LEN];
+ uint8_t gateway[IP_ADDR_LEN];
+ uint32_t ipv6_options;
+ uint32_t ipv6_addl_options;
+ uint8_t ipv6_link_local_state;
+ uint8_t ipv6_addr0_state;
+ uint8_t ipv6_addr1_state;
+ uint8_t ipv6_default_router_state;
+ uint16_t ipv6_vlan_tag;
+ struct in6_addr ipv6_link_local_addr;
+ struct in6_addr ipv6_addr0;
+ struct in6_addr ipv6_addr1;
+ struct in6_addr ipv6_default_router_addr;
+};
+
/*
* Linux Host Adapter structure
*/
@@ -452,10 +474,6 @@ struct scsi_qla_host {
/* --- From Init_FW --- */
/* init_cb_t *init_cb; */
uint16_t firmware_options;
- uint16_t tcp_options;
- uint8_t ip_address[IP_ADDR_LEN];
- uint8_t subnet_mask[IP_ADDR_LEN];
- uint8_t gateway[IP_ADDR_LEN];
uint8_t alias[32];
uint8_t name_string[256];
uint8_t heartbeat_interval;
@@ -534,22 +552,7 @@ struct scsi_qla_host {
/* Saved srb for status continuation entry processing */
struct srb *status_srb;
- /* IPv6 support info from InitFW */
uint8_t acb_version;
- uint8_t ipv4_addr_state;
- uint16_t ipv4_options;
-
- uint32_t resvd2;
- uint32_t ipv6_options;
- uint32_t ipv6_addl_options;
- uint8_t ipv6_link_local_state;
- uint8_t ipv6_addr0_state;
- uint8_t ipv6_addr1_state;
- uint8_t ipv6_default_router_state;
- struct in6_addr ipv6_link_local_addr;
- struct in6_addr ipv6_addr0;
- struct in6_addr ipv6_addr1;
- struct in6_addr ipv6_default_router_addr;
/* qla82xx specific fields */
struct device_reg_82xx __iomem *qla4_8xxx_reg; /* Base I/O address */
@@ -584,16 +587,18 @@ struct scsi_qla_host {
uint32_t nx_reset_timeout;
struct completion mbx_intr_comp;
+ struct ipaddress_config ip_config;
};
static inline int is_ipv4_enabled(struct scsi_qla_host *ha)
{
- return ((ha->ipv4_options & IPOPT_IPv4_PROTOCOL_ENABLE) != 0);
+ return ((ha->ip_config.ipv4_options & IPOPT_IPV4_PROTOCOL_ENABLE) != 0);
}
static inline int is_ipv6_enabled(struct scsi_qla_host *ha)
{
- return ((ha->ipv6_options & IPV6_OPT_IPV6_PROTOCOL_ENABLE) != 0);
+ return ((ha->ip_config.ipv6_options &
+ IPV6_OPT_IPV6_PROTOCOL_ENABLE) != 0);
}
static inline int is_qla4010(struct scsi_qla_host *ha)
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
index d05e8be..9a07b8d 100644
--- a/drivers/scsi/qla4xxx/ql4_fw.h
+++ b/drivers/scsi/qla4xxx/ql4_fw.h
@@ -483,7 +483,7 @@ struct addr_ctrl_blk {
uint16_t ipv4_tcp_opts; /* 32-33 */
#define TCPOPT_DHCP_ENABLE 0x0200
uint16_t ipv4_ip_opts; /* 34-35 */
-#define IPOPT_IPv4_PROTOCOL_ENABLE 0x8000
+#define IPOPT_IPV4_PROTOCOL_ENABLE 0x8000
uint16_t iscsi_max_pdu_size; /* 36-37 */
uint8_t ipv4_tos; /* 38 */
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
index 48e2241..1f267d8 100644
--- a/drivers/scsi/qla4xxx/ql4_init.c
+++ b/drivers/scsi/qla4xxx/ql4_init.c
@@ -236,38 +236,44 @@ qla4xxx_wait_for_ip_config(struct scsi_qla_host *ha)
FW_ADDSTATE_DHCPv4_LEASE_ACQUIRED) == 0)) {
ipv4_wait = 1;
}
- if (((ha->ipv6_addl_options &
- IPV6_ADDOPT_NEIGHBOR_DISCOVERY_ADDR_ENABLE) != 0) &&
- ((ha->ipv6_link_local_state == IP_ADDRSTATE_ACQUIRING) ||
- (ha->ipv6_addr0_state == IP_ADDRSTATE_ACQUIRING) ||
- (ha->ipv6_addr1_state == IP_ADDRSTATE_ACQUIRING))) {
+ if (((ha->ip_config.ipv6_addl_options &
+ IPV6_ADDOPT_NEIGHBOR_DISCOVERY_ADDR_ENABLE) != 0) &&
+ ((ha->ip_config.ipv6_link_local_state ==
+ IP_ADDRSTATE_ACQUIRING) ||
+ (ha->ip_config.ipv6_addr0_state ==
+ IP_ADDRSTATE_ACQUIRING) ||
+ (ha->ip_config.ipv6_addr1_state ==
+ IP_ADDRSTATE_ACQUIRING))) {
ipv6_wait = 1;
- if ((ha->ipv6_link_local_state ==
- IP_ADDRSTATE_PREFERRED) ||
- (ha->ipv6_addr0_state == IP_ADDRSTATE_PREFERRED) ||
- (ha->ipv6_addr1_state == IP_ADDRSTATE_PREFERRED)) {
+ if ((ha->ip_config.ipv6_link_local_state ==
+ IP_ADDRSTATE_PREFERRED) ||
+ (ha->ip_config.ipv6_addr0_state ==
+ IP_ADDRSTATE_PREFERRED) ||
+ (ha->ip_config.ipv6_addr1_state ==
+ IP_ADDRSTATE_PREFERRED)) {
DEBUG2(printk(KERN_INFO "scsi%ld: %s: "
"Preferred IP configured."
" Don't wait!\n", ha->host_no,
__func__));
ipv6_wait = 0;
}
- if (memcmp(&ha->ipv6_default_router_addr, ip_address,
- IPv6_ADDR_LEN) == 0) {
+ if (memcmp(&ha->ip_config.ipv6_default_router_addr,
+ ip_address, IPv6_ADDR_LEN) == 0) {
DEBUG2(printk(KERN_INFO "scsi%ld: %s: "
"No Router configured. "
"Don't wait!\n", ha->host_no,
__func__));
ipv6_wait = 0;
}
- if ((ha->ipv6_default_router_state ==
- IPV6_RTRSTATE_MANUAL) &&
- (ha->ipv6_link_local_state ==
- IP_ADDRSTATE_TENTATIVE) &&
- (memcmp(&ha->ipv6_link_local_addr,
- &ha->ipv6_default_router_addr, 4) == 0)) {
+ if ((ha->ip_config.ipv6_default_router_state ==
+ IPV6_RTRSTATE_MANUAL) &&
+ (ha->ip_config.ipv6_link_local_state ==
+ IP_ADDRSTATE_TENTATIVE) &&
+ (memcmp(&ha->ip_config.ipv6_link_local_addr,
+ &ha->ip_config.ipv6_default_router_addr, 4) ==
+ 0)) {
DEBUG2(printk("scsi%ld: %s: LinkLocal Router & "
"IP configured. Don't wait!\n",
ha->host_no, __func__));
@@ -279,11 +285,14 @@ qla4xxx_wait_for_ip_config(struct scsi_qla_host *ha)
"IP(s) \"", ha->host_no, __func__));
if (ipv4_wait)
DEBUG2(printk("IPv4 "));
- if (ha->ipv6_link_local_state == IP_ADDRSTATE_ACQUIRING)
+ if (ha->ip_config.ipv6_link_local_state ==
+ IP_ADDRSTATE_ACQUIRING)
DEBUG2(printk("IPv6LinkLocal "));
- if (ha->ipv6_addr0_state == IP_ADDRSTATE_ACQUIRING)
+ if (ha->ip_config.ipv6_addr0_state ==
+ IP_ADDRSTATE_ACQUIRING)
DEBUG2(printk("IPv6Addr0 "));
- if (ha->ipv6_addr1_state == IP_ADDRSTATE_ACQUIRING)
+ if (ha->ip_config.ipv6_addr1_state ==
+ IP_ADDRSTATE_ACQUIRING)
DEBUG2(printk("IPv6Addr1 "));
DEBUG2(printk("\"\n"));
}
@@ -1297,8 +1306,8 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha,
goto exit_init_online;
/* Skip device discovery if ip and subnet is zero */
- if (memcmp(ha->ip_address, ip_address, IP_ADDR_LEN) == 0 ||
- memcmp(ha->subnet_mask, ip_address, IP_ADDR_LEN) == 0)
+ if (memcmp(ha->ip_config.ip_address, ip_address, IP_ADDR_LEN) == 0 ||
+ memcmp(ha->ip_config.subnet_mask, ip_address, IP_ADDR_LEN) == 0)
goto exit_init_online;
if (renew_ddb_list == PRESERVE_DDB_LIST) {
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index 743290e..d213fa7 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -341,39 +341,57 @@ qla4xxx_get_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
static void
qla4xxx_update_local_ip(struct scsi_qla_host *ha,
- struct addr_ctrl_blk *init_fw_cb)
+ struct addr_ctrl_blk *init_fw_cb)
{
+ 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);
+
+ if (ha->acb_version == ACB_SUPPORTED) {
+ 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);
+ }
+
/* Save IPv4 Address Info */
- memcpy(ha->ip_address, init_fw_cb->ipv4_addr,
- min(sizeof(ha->ip_address), sizeof(init_fw_cb->ipv4_addr)));
- memcpy(ha->subnet_mask, init_fw_cb->ipv4_subnet,
- min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->ipv4_subnet)));
- memcpy(ha->gateway, init_fw_cb->ipv4_gw_addr,
- min(sizeof(ha->gateway), sizeof(init_fw_cb->ipv4_gw_addr)));
+ memcpy(ha->ip_config.ip_address, init_fw_cb->ipv4_addr,
+ min(sizeof(ha->ip_config.ip_address),
+ sizeof(init_fw_cb->ipv4_addr)));
+ memcpy(ha->ip_config.subnet_mask, init_fw_cb->ipv4_subnet,
+ min(sizeof(ha->ip_config.subnet_mask),
+ sizeof(init_fw_cb->ipv4_subnet)));
+ memcpy(ha->ip_config.gateway, init_fw_cb->ipv4_gw_addr,
+ min(sizeof(ha->ip_config.gateway),
+ sizeof(init_fw_cb->ipv4_gw_addr)));
if (is_ipv6_enabled(ha)) {
/* Save IPv6 Address */
- ha->ipv6_link_local_state = init_fw_cb->ipv6_lnk_lcl_addr_state;
- ha->ipv6_addr0_state = init_fw_cb->ipv6_addr0_state;
- ha->ipv6_addr1_state = init_fw_cb->ipv6_addr1_state;
- ha->ipv6_default_router_state = init_fw_cb->ipv6_dflt_rtr_state;
- ha->ipv6_link_local_addr.in6_u.u6_addr8[0] = 0xFE;
- ha->ipv6_link_local_addr.in6_u.u6_addr8[1] = 0x80;
-
- memcpy(&ha->ipv6_link_local_addr.in6_u.u6_addr8[8],
- init_fw_cb->ipv6_if_id,
- min(sizeof(ha->ipv6_link_local_addr)/2,
- sizeof(init_fw_cb->ipv6_if_id)));
- memcpy(&ha->ipv6_addr0, init_fw_cb->ipv6_addr0,
- min(sizeof(ha->ipv6_addr0),
- sizeof(init_fw_cb->ipv6_addr0)));
- memcpy(&ha->ipv6_addr1, init_fw_cb->ipv6_addr1,
- min(sizeof(ha->ipv6_addr1),
- sizeof(init_fw_cb->ipv6_addr1)));
- memcpy(&ha->ipv6_default_router_addr,
- init_fw_cb->ipv6_dflt_rtr_addr,
- min(sizeof(ha->ipv6_default_router_addr),
- sizeof(init_fw_cb->ipv6_dflt_rtr_addr)));
+ ha->ip_config.ipv6_link_local_state =
+ le16_to_cpu(init_fw_cb->ipv6_lnk_lcl_addr_state);
+ ha->ip_config.ipv6_addr0_state =
+ le16_to_cpu(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);
+ 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;
+
+ memcpy(&ha->ip_config.ipv6_link_local_addr.in6_u.u6_addr8[8],
+ init_fw_cb->ipv6_if_id,
+ min(sizeof(ha->ip_config.ipv6_link_local_addr)/2,
+ sizeof(init_fw_cb->ipv6_if_id)));
+ memcpy(&ha->ip_config.ipv6_addr0, init_fw_cb->ipv6_addr0,
+ min(sizeof(ha->ip_config.ipv6_addr0),
+ sizeof(init_fw_cb->ipv6_addr0)));
+ memcpy(&ha->ip_config.ipv6_addr1, init_fw_cb->ipv6_addr1,
+ min(sizeof(ha->ip_config.ipv6_addr1),
+ sizeof(init_fw_cb->ipv6_addr1)));
+ memcpy(&ha->ip_config.ipv6_default_router_addr,
+ init_fw_cb->ipv6_dflt_rtr_addr,
+ min(sizeof(ha->ip_config.ipv6_default_router_addr),
+ sizeof(init_fw_cb->ipv6_dflt_rtr_addr)));
}
}
@@ -397,9 +415,6 @@ qla4xxx_update_local_ifcb(struct scsi_qla_host *ha,
/* Save some info in adapter structure. */
ha->acb_version = init_fw_cb->acb_version;
ha->firmware_options = le16_to_cpu(init_fw_cb->fw_options);
- ha->tcp_options = le16_to_cpu(init_fw_cb->ipv4_tcp_opts);
- ha->ipv4_options = le16_to_cpu(init_fw_cb->ipv4_ip_opts);
- ha->ipv4_addr_state = le16_to_cpu(init_fw_cb->ipv4_addr_state);
ha->heartbeat_interval = init_fw_cb->hb_interval;
memcpy(ha->name_string, init_fw_cb->iscsi_name,
min(sizeof(ha->name_string),
@@ -407,10 +422,6 @@ qla4xxx_update_local_ifcb(struct scsi_qla_host *ha,
/*memcpy(ha->alias, init_fw_cb->Alias,
min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/
- if (ha->acb_version == ACB_SUPPORTED) {
- ha->ipv6_options = init_fw_cb->ipv6_opts;
- ha->ipv6_addl_options = init_fw_cb->ipv6_addtl_opts;
- }
qla4xxx_update_local_ip(ha, init_fw_cb);
return QLA_SUCCESS;
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index e9b669d..09e371f 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -190,9 +190,7 @@ static int qla4xxx_host_get_param(struct Scsi_Host *shost,
len = sysfs_format_mac(buf, ha->my_mac, MAC_ADDR_LEN);
break;
case ISCSI_HOST_PARAM_IPADDRESS:
- len = sprintf(buf, "%d.%d.%d.%d\n", ha->ip_address[0],
- ha->ip_address[1], ha->ip_address[2],
- ha->ip_address[3]);
+ len = sprintf(buf, "%pI4\n", &ha->ip_config.ip_address);
break;
case ISCSI_HOST_PARAM_INITIATOR_NAME:
len = sprintf(buf, "%s\n", ha->name_string);
@@ -328,10 +326,10 @@ static inline void qla4xxx_set_ipv4(struct scsi_qla_host *ha,
case ISCSI_NET_PARAM_IFACE_ENABLED:
if (net_param->value[0] == ISCSI_TRUE)
init_fw_cb->ipv4_ip_opts |=
- cpu_to_le16(IPOPT_IPv4_PROTOCOL_ENABLE);
+ cpu_to_le16(IPOPT_IPV4_PROTOCOL_ENABLE);
else
init_fw_cb->ipv4_ip_opts &=
- cpu_to_le16(~IPOPT_IPv4_PROTOCOL_ENABLE &
+ cpu_to_le16(~IPOPT_IPV4_PROTOCOL_ENABLE &
0xFFFF);
break;
case ISCSI_NET_PARAM_VLAN:
--
1.7.3.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/5] iscsi_transport: show network configuration in sysfs
2011-04-22 18:07 [PATCH 0/5] qla4xxx: Proposal for iSCSI Network Configuration vikas.chaudhary
` (2 preceding siblings ...)
2011-04-22 18:07 ` [PATCH 3/5] qla4xxx: Added new "struct ipaddress_config" vikas.chaudhary
@ 2011-04-22 18:07 ` vikas.chaudhary
2011-04-23 22:40 ` Mike Christie
2011-04-22 18:07 ` [PATCH 5/5] qla4xxx: added support to show multiple iface " vikas.chaudhary
4 siblings, 1 reply; 8+ messages in thread
From: vikas.chaudhary @ 2011-04-22 18:07 UTC (permalink / raw)
To: James.Bottomley, michaelc
Cc: linux-scsi, vikas.chaudhary, lalit.chandivade, ravi.anand
From: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
To support multiple network addresses per adapter need to have a new way to
represent network interface (net iface) in sysfs.
Currently only one ipaddress and hwaddress is displayed
\# ls /sys/class/iscsi_host/host18
device hwaddress initiatorname ipaddress power subsystem uevent
In this patch the net iface is presented as a separate class device.
The one that can be added/removed dynamically or statically, based on how
the user configures the multiple net iface on the adapter.
The new sysfs directory would look like this
\# /sys/class/iscsi_iface/
|
|- ipv4-iface-<host_no>-<iface_no>/ <-- for ipv4
|- ipaddress
|- subnet
|- gateway
|- bootproto
|- enabled
|- ipv6-iface-<host_no>-<iface_no>/ <-- for ipv6
|- ipaddress
|- link_local_addr
|- router_addr
|- ipaddr_autocfg
|- linklocal_autocfg
|- enabled
We can also get above .iscsi_iface. class from:-
\# /sys/class/iscsi_host/host12/device/iscsi_iface/
With this change, iscsadm would need changes to create iface by getting
hw/ip related data from new sysfs path.
The old path still can be maintained to keep backward compatibility.
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Signed-off-by: Lalit Chandivade <lalit.chandivade@qlogic.com>
Reviewed-by: Harish Zunjarrao <harish.zunjarrao@qlogic.com>
---
drivers/scsi/scsi_transport_iscsi.c | 179 ++++++++++++++++++++++++++++++++++-
include/scsi/iscsi_if.h | 17 ++++
include/scsi/scsi_transport_iscsi.h | 24 +++++
3 files changed, 219 insertions(+), 1 deletions(-)
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 7596234..76967a7 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -270,6 +270,155 @@ struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle)
}
EXPORT_SYMBOL_GPL(iscsi_lookup_endpoint);
+/*
+ * Interface to display network param to sysfs
+ */
+
+static void iscsi_iface_release(struct device *dev)
+{
+ struct iscsi_iface *iface = iscsi_dev_to_iface(dev);
+ kfree(iface);
+}
+
+static struct class iscsi_iface_class = {
+ .name = "iscsi_iface",
+ .dev_release = iscsi_iface_release,
+};
+
+#define ISCSI_IFACE_ATTR(_prefix, _name, _mode, _show, _store) \
+struct device_attribute dev_attr_##_prefix##_##_name = \
+ __ATTR(_name, _mode, _show, _store)
+
+/* iface attrs show */
+#define iscsi_iface_attr_show(type, name, param) \
+static ssize_t \
+show_##type##_##name(struct device *dev, struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct iscsi_iface *iface = iscsi_dev_to_iface(dev); \
+ struct iscsi_transport *t = iface->transport; \
+ return t->get_iface_param(iface, param, buf); \
+} \
+
+#define iscsi_iface_attr(type, name, param) \
+ iscsi_iface_attr_show(type, name, param) \
+static ISCSI_IFACE_ATTR(type, name, S_IRUGO, show_##type##_##name, NULL);
+
+/* generic read only ipvi4 attribute */
+iscsi_iface_attr(ipv4_iface, ipaddress, ISCSI_NET_PARAM_IPV4_ADDR);
+iscsi_iface_attr(ipv4_iface, gateway, ISCSI_NET_PARAM_IPV4_GW);
+iscsi_iface_attr(ipv4_iface, subnet, ISCSI_NET_PARAM_IPV4_SUBNET);
+iscsi_iface_attr(ipv4_iface, enabled, ISCSI_NET_PARAM_IFACE_ENABLED);
+iscsi_iface_attr(ipv4_iface, bootproto, ISCSI_NET_PARAM_IPV4_BOOTPROTO);
+
+/* generic read only ipv6 attribute */
+iscsi_iface_attr(ipv6_iface, ipaddress, ISCSI_NET_PARAM_IPV6_ADDR);
+iscsi_iface_attr(ipv6_iface, link_local_addr, ISCSI_NET_PARAM_IPV6_LINKLOCAL);
+iscsi_iface_attr(ipv6_iface, router_addr, ISCSI_NET_PARAM_IPV6_ROUTER);
+iscsi_iface_attr(ipv6_iface, ipaddr_autocfg,
+ ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG);
+iscsi_iface_attr(ipv6_iface, linklocal_autocfg,
+ ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG);
+iscsi_iface_attr(ipv6_iface, enabled, ISCSI_NET_PARAM_IFACE_ENABLED);
+
+/* IPv4 Attrs */
+#define ISCSI_IPV4_IFACE_ATTRS 5
+static struct attribute *iscsi_ipv4_iface_attrs[ISCSI_IPV4_IFACE_ATTRS + 1];
+
+#define SETUP_IPV4_IFACE_RD_ATTR(field, param_flag) \
+do { \
+ if (tt->ipv4_iface_param_mask & param_flag) { \
+ iscsi_ipv4_iface_attrs[count] = \
+ &dev_attr_ipv4_iface_##field.attr; \
+ count++; \
+ } \
+} while (0)
+
+static struct attribute_group iscsi_ipv4_iface_group = {
+ .attrs = iscsi_ipv4_iface_attrs,
+};
+
+/* IPv6 Attrs */
+#define ISCSI_IPV6_IFACE_ATTRS 6
+static struct attribute *iscsi_ipv6_iface_attrs[ISCSI_IPV6_IFACE_ATTRS + 1];
+
+#define SETUP_IPV6_IFACE_RD_ATTR(field, param_flag) \
+do { \
+ if (tt->ipv6_iface_param_mask & param_flag) { \
+ iscsi_ipv6_iface_attrs[count] = \
+ &dev_attr_ipv6_iface_##field.attr; \
+ count++; \
+ } \
+} while (0)
+
+static struct attribute_group iscsi_ipv6_iface_group = {
+ .attrs = iscsi_ipv6_iface_attrs,
+};
+
+struct iscsi_iface *
+iscsi_create_iface(struct Scsi_Host *shost, struct iscsi_transport *transport,
+ uint32_t iface_type, uint32_t iface_num, int dd_size)
+{
+ struct iscsi_iface *iface;
+ int err;
+
+ iface = kzalloc(sizeof(*iface) + dd_size, GFP_KERNEL);
+ if (!iface)
+ return NULL;
+
+ iface->transport = transport;
+ iface->iface_type = iface_type;
+ iface->iface_num = iface_num;
+ iface->dev.class = &iscsi_iface_class;
+ /* parent reference */
+ iface->dev.parent = get_device(&shost->shost_gendev);
+ if (iface_type == IFACE_TYPE_IPV4)
+ dev_set_name(&iface->dev, "ipv4-iface-%u-%u", shost->host_no,
+ iface_num);
+ else if (iface_type == IFACE_TYPE_IPV6)
+ dev_set_name(&iface->dev, "ipv6-iface-%u-%u", shost->host_no,
+ iface_num);
+ else
+ goto free_iface;
+
+ err = device_register(&iface->dev);
+ if (err)
+ goto free_iface;
+
+ if (iface_type == IFACE_TYPE_IPV4)
+ err = sysfs_create_group(&iface->dev.kobj,
+ &iscsi_ipv4_iface_group);
+ else if (iface_type == IFACE_TYPE_IPV6)
+ err = sysfs_create_group(&iface->dev.kobj,
+ &iscsi_ipv6_iface_group);
+
+ if (err)
+ goto iface_unregister_dev;
+
+ if (dd_size)
+ iface->dd_data = &iface[1];
+ return iface;
+
+iface_unregister_dev:
+ device_unregister(&iface->dev);
+
+free_iface:
+ kfree(iface);
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(iscsi_create_iface);
+
+void iscsi_destroy_iface(struct iscsi_iface *iface)
+{
+ if (iface->iface_type == IFACE_TYPE_IPV6)
+ sysfs_remove_group(&iface->dev.kobj, &iscsi_ipv6_iface_group);
+ else
+ sysfs_remove_group(&iface->dev.kobj, &iscsi_ipv4_iface_group);
+
+ device_unregister(&iface->dev);
+}
+EXPORT_SYMBOL_GPL(iscsi_destroy_iface);
+
static int iscsi_setup_host(struct transport_container *tc, struct device *dev,
struct device *cdev)
{
@@ -2175,6 +2324,27 @@ iscsi_register_transport(struct iscsi_transport *tt)
BUG_ON(count > ISCSI_SESSION_ATTRS);
priv->session_attrs[count] = NULL;
+ count = 0;
+
+ SETUP_IPV4_IFACE_RD_ATTR(ipaddress, ISCSI_NET_IPV4_ADDR);
+ SETUP_IPV4_IFACE_RD_ATTR(gateway, ISCSI_NET_IPV4_GW);
+ SETUP_IPV4_IFACE_RD_ATTR(subnet, ISCSI_NET_IPV4_SUBNET);
+ SETUP_IPV4_IFACE_RD_ATTR(bootproto, ISCSI_NET_IPV4_BOOTPROTO);
+ SETUP_IPV4_IFACE_RD_ATTR(enabled, ISCSI_NET_IFACE_ENABLED);
+ BUG_ON(count > ISCSI_IPV4_IFACE_ATTRS);
+ iscsi_ipv4_iface_attrs[count] = NULL;
+ count = 0;
+
+ SETUP_IPV6_IFACE_RD_ATTR(ipaddress, ISCSI_NET_IPV6_ADDR);
+ SETUP_IPV6_IFACE_RD_ATTR(link_local_addr, ISCSI_NET_IPV6_LINKLOCAL);
+ SETUP_IPV6_IFACE_RD_ATTR(router_addr, ISCSI_NET_IPV6_ROUTER);
+ SETUP_IPV6_IFACE_RD_ATTR(ipaddr_autocfg,
+ ISCSI_NET_IPV6_ADDR_AUTOCFG);
+ SETUP_IPV6_IFACE_RD_ATTR(linklocal_autocfg,
+ ISCSI_NET_IPV6_LINKLOCAL_AUTOCFG);
+ SETUP_IPV6_IFACE_RD_ATTR(enabled, ISCSI_NET_IFACE_ENABLED);
+ BUG_ON(count > ISCSI_IPV6_IFACE_ATTRS);
+ iscsi_ipv6_iface_attrs[count] = NULL;
spin_lock_irqsave(&iscsi_transport_lock, flags);
list_add(&priv->list, &iscsi_transports);
@@ -2237,10 +2407,14 @@ static __init int iscsi_transport_init(void)
if (err)
goto unregister_transport_class;
- err = transport_class_register(&iscsi_host_class);
+ err = class_register(&iscsi_iface_class);
if (err)
goto unregister_endpoint_class;
+ err = transport_class_register(&iscsi_host_class);
+ if (err)
+ goto unregister_iface_class;
+
err = transport_class_register(&iscsi_connection_class);
if (err)
goto unregister_host_class;
@@ -2270,6 +2444,8 @@ unregister_conn_class:
transport_class_unregister(&iscsi_connection_class);
unregister_host_class:
transport_class_unregister(&iscsi_host_class);
+unregister_iface_class:
+ class_unregister(&iscsi_iface_class);
unregister_endpoint_class:
class_unregister(&iscsi_endpoint_class);
unregister_transport_class:
@@ -2285,6 +2461,7 @@ static void __exit iscsi_transport_exit(void)
transport_class_unregister(&iscsi_session_class);
transport_class_unregister(&iscsi_host_class);
class_unregister(&iscsi_endpoint_class);
+ class_unregister(&iscsi_iface_class);
class_unregister(&iscsi_transport_class);
}
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index 449e55b..6282f8b 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -279,6 +279,23 @@ enum iscsi_net_param_type {
ISCSI_NET_PARAM_VLAN = 13,
};
+#define ISCSI_NET_IPV4_ADDR (1ULL << ISCSI_NET_PARAM_IPV4_ADDR)
+#define ISCSI_NET_IPV4_SUBNET (1ULL << ISCSI_NET_PARAM_IPV4_SUBNET)
+#define ISCSI_NET_IPV4_GW (1ULL << ISCSI_NET_PARAM_IPV4_GW)
+#define ISCSI_NET_IPV4_BOOTPROTO (1ULL << ISCSI_NET_PARAM_IPV4_BOOTPROTO)
+#define ISCSI_NET_MAC (1ULL << ISCSI_NET_PARAM_MAC)
+#define ISCSI_NET_IPV6_LINKLOCAL (1ULL << ISCSI_NET_PARAM_IPV6_LINKLOCAL)
+#define ISCSI_NET_IPV6_ADDR (1ULL << ISCSI_NET_PARAM_IPV6_ADDR)
+#define ISCSI_NET_IPV6_ROUTER (1ULL << ISCSI_NET_PARAM_IPV6_ROUTER)
+#define ISCSI_NET_IPV6_ADDR_AUTOCFG \
+ (1ULL << ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG)
+#define ISCSI_NET_IPV6_LINKLOCAL_AUTOCFG \
+ (1ULL << ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG)
+#define ISCSI_NET_IPV6_ROUTER_AUTOCFG \
+ (1ULL << ISCSI_NET_PARAM_IPV6_ROUTER_AUTOCFG)
+#define ISCSI_NET_IFACE_ENABLED (1ULL << ISCSI_NET_PARAM_IFACE_ENABLED)
+#define ISCSI_NET_VLAN (1ULL << ISCSI_NET_PARAM_VLAN)
+
/* 20 param per iface * 10 iface per port = 200 params */
#define ISCSI_MAX_IFACE_PER_HW 10
#define ISCSI_MAX_PARAM_PER_IFACE 20
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index 45b9df9..09a0108 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -37,6 +37,7 @@ struct iscsi_cls_conn;
struct iscsi_conn;
struct iscsi_task;
struct sockaddr;
+struct iscsi_iface;
/**
* struct iscsi_transport - iSCSI Transport template
@@ -87,6 +88,8 @@ struct iscsi_transport {
/* LLD sets this to indicate what values it can export to sysfs */
uint64_t param_mask;
uint64_t host_param_mask;
+ uint64_t ipv4_iface_param_mask;
+ uint64_t ipv6_iface_param_mask;
struct iscsi_cls_session *(*create_session) (struct iscsi_endpoint *ep,
uint16_t cmds_max, uint16_t qdepth,
uint32_t sn);
@@ -138,6 +141,8 @@ struct iscsi_transport {
uint32_t enable, struct sockaddr *dst_addr);
int (*set_path) (struct Scsi_Host *shost, struct iscsi_path *params);
int (*set_net_config) (struct Scsi_Host *shost, char *data, int count);
+ int (*get_iface_param) (struct iscsi_iface *iface,
+ enum iscsi_net_param_type param, char *buf);
};
/*
@@ -229,6 +234,19 @@ struct iscsi_endpoint {
struct iscsi_cls_conn *conn;
};
+struct iscsi_iface {
+ struct device dev;
+ struct iscsi_transport *transport;
+ uint32_t iface_type; /* IPv4 or IPv6 */
+ uint32_t iface_num; /* iface number, 0 - n */
+ void *dd_data; /* LLD private data */
+};
+
+#define iscsi_dev_to_iface(_dev) \
+ container_of(_dev, struct iscsi_iface, dev)
+#define iscsi_iface_to_shost(_iface) \
+ dev_to_shost(_iface->dev.parent)
+
/*
* session and connection functions that can be used by HW iSCSI LLDs
*/
@@ -262,5 +280,11 @@ extern struct iscsi_endpoint *iscsi_create_endpoint(int dd_size);
extern void iscsi_destroy_endpoint(struct iscsi_endpoint *ep);
extern struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle);
extern int iscsi_block_scsi_eh(struct scsi_cmnd *cmd);
+extern struct iscsi_iface *iscsi_create_iface(struct Scsi_Host *shost,
+ struct iscsi_transport *t,
+ uint32_t iface_type,
+ uint32_t iface_num, int dd_size);
+extern void iscsi_destroy_iface(struct iscsi_iface *iface);
+extern struct iscsi_iface *iscsi_lookup_iface(int handle);
#endif
--
1.7.3.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5/5] qla4xxx: added support to show multiple iface in sysfs
2011-04-22 18:07 [PATCH 0/5] qla4xxx: Proposal for iSCSI Network Configuration vikas.chaudhary
` (3 preceding siblings ...)
2011-04-22 18:07 ` [PATCH 4/5] iscsi_transport: show network configuration in sysfs vikas.chaudhary
@ 2011-04-22 18:07 ` vikas.chaudhary
4 siblings, 0 replies; 8+ messages in thread
From: vikas.chaudhary @ 2011-04-22 18:07 UTC (permalink / raw)
To: James.Bottomley, michaelc
Cc: linux-scsi, vikas.chaudhary, lalit.chandivade, ravi.anand
From: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Reviewed-by: Lalit Chandivade <lalit.chandivade@qlogic.com>
Reviewed-by: Harish Zunjarrao <harish.zunjarrao@qlogic.com>
---
drivers/scsi/qla4xxx/ql4_def.h | 3 +
drivers/scsi/qla4xxx/ql4_os.c | 114 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 117 insertions(+), 0 deletions(-)
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index bce5c89..3a0316c 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -588,6 +588,9 @@ struct scsi_qla_host {
struct completion mbx_intr_comp;
struct ipaddress_config ip_config;
+ struct iscsi_iface *iface_ipv4;
+ struct iscsi_iface *iface_ipv6_1;
+ struct iscsi_iface *iface_ipv6_2;
};
static inline int is_ipv4_enabled(struct scsi_qla_host *ha)
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 09e371f..673deb3 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -82,6 +82,8 @@ static int qla4xxx_host_get_param(struct Scsi_Host *shost,
enum iscsi_host_param param, char *buf);
static int qla4xxx_set_net_config(struct Scsi_Host *shost, char *data,
int count);
+static int qla4xxx_get_iface_param(struct iscsi_iface *iface,
+ enum iscsi_net_param_type param, char *buf);
static void qla4xxx_recovery_timedout(struct iscsi_cls_session *session);
static enum blk_eh_timer_return qla4xxx_eh_cmd_timed_out(struct scsi_cmnd *sc);
@@ -139,16 +141,95 @@ static struct iscsi_transport qla4xxx_iscsi_transport = {
.host_param_mask = ISCSI_HOST_HWADDRESS |
ISCSI_HOST_IPADDRESS |
ISCSI_HOST_INITIATOR_NAME,
+ .ipv4_iface_param_mask = ISCSI_NET_IPV4_ADDR |
+ ISCSI_NET_IPV4_SUBNET |
+ ISCSI_NET_IPV4_GW |
+ ISCSI_NET_IPV4_BOOTPROTO |
+ ISCSI_NET_IFACE_ENABLED,
+ .ipv6_iface_param_mask = ISCSI_NET_IPV6_LINKLOCAL |
+ ISCSI_NET_IPV6_ADDR |
+ ISCSI_NET_IPV6_ROUTER |
+ ISCSI_NET_IPV6_ADDR_AUTOCFG |
+ ISCSI_NET_IPV6_LINKLOCAL_AUTOCFG |
+ ISCSI_NET_IFACE_ENABLED,
.tgt_dscvr = qla4xxx_tgt_dscvr,
.get_conn_param = qla4xxx_conn_get_param,
.get_session_param = qla4xxx_sess_get_param,
.get_host_param = qla4xxx_host_get_param,
.set_net_config = qla4xxx_set_net_config,
.session_recovery_timedout = qla4xxx_recovery_timedout,
+ .get_iface_param = qla4xxx_get_iface_param,
};
static struct scsi_transport_template *qla4xxx_scsi_transport;
+static int qla4xxx_get_iface_param(struct iscsi_iface *iface,
+ enum iscsi_net_param_type param, char *buf)
+{
+ struct Scsi_Host *shost = iscsi_iface_to_shost(iface);
+ struct scsi_qla_host *ha = to_qla_host(shost);
+ int len = -ENOSYS;
+
+ switch (param) {
+ case ISCSI_NET_PARAM_IPV4_ADDR:
+ len = sprintf(buf, "%pI4\n", &ha->ip_config.ip_address);
+ break;
+ case ISCSI_NET_PARAM_IPV4_SUBNET:
+ len = sprintf(buf, "%pI4\n", &ha->ip_config.subnet_mask);
+ break;
+ case ISCSI_NET_PARAM_IPV4_GW:
+ len = sprintf(buf, "%pI4\n", &ha->ip_config.gateway);
+ break;
+ case ISCSI_NET_PARAM_IFACE_ENABLED:
+ if (iface->iface_type == IFACE_TYPE_IPV4)
+ len = sprintf(buf, "%s\n",
+ (ha->ip_config.ipv4_options &
+ IPOPT_IPV4_PROTOCOL_ENABLE) ?
+ "true" : "false");
+ else if (iface->iface_type == IFACE_TYPE_IPV6)
+ len = sprintf(buf, "%s\n",
+ (ha->ip_config.ipv6_options &
+ IPV6_OPT_IPV6_PROTOCOL_ENABLE) ?
+ "true" : "false");
+ break;
+ case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
+ len = sprintf(buf, "%s\n",
+ (ha->ip_config.tcp_options & TCPOPT_DHCP_ENABLE) ?
+ "dhcp" : "static");
+ break;
+ case ISCSI_NET_PARAM_IPV6_ADDR:
+ if (iface->iface_num == 1)
+ len = sprintf(buf, "%pI6\n", &ha->ip_config.ipv6_addr0);
+ if (iface->iface_num == 2)
+ len = sprintf(buf, "%pI6\n", &ha->ip_config.ipv6_addr1);
+ break;
+ case ISCSI_NET_PARAM_IPV6_LINKLOCAL:
+ len = sprintf(buf, "%pI6\n",
+ &ha->ip_config.ipv6_link_local_addr);
+ break;
+ case ISCSI_NET_PARAM_IPV6_ROUTER:
+ len = sprintf(buf, "%pI6\n",
+ &ha->ip_config.ipv6_default_router_addr);
+ break;
+ case ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG:
+ len = sprintf(buf, "%s\n",
+ (ha->ip_config.ipv6_addl_options &
+ IPV6_ADDOPT_NEIGHBOR_DISCOVERY_ADDR_ENABLE) ?
+ "nd" : "static");
+ break;
+ case ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG:
+ len = sprintf(buf, "%s\n",
+ (ha->ip_config.ipv6_addl_options &
+ IPV6_ADDOPT_AUTOCONFIG_LINK_LOCAL_ADDR) ?
+ "auto" : "static");
+ break;
+ default:
+ len = -ENOSYS;
+ }
+
+ return len;
+}
+
static enum blk_eh_timer_return qla4xxx_eh_cmd_timed_out(struct scsi_cmnd *sc)
{
struct iscsi_cls_session *session;
@@ -1899,6 +1980,34 @@ uint16_t qla4_8xxx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha)
return (uint16_t)le32_to_cpu(readl(&ha->qla4_8xxx_reg->rsp_q_in));
}
+static void qla4xxx_create_iface(struct scsi_qla_host *ha)
+{
+ /* IPv4 */
+ ha->iface_ipv4 = iscsi_create_iface(ha->host,
+ &qla4xxx_iscsi_transport,
+ IFACE_TYPE_IPV4, 1, 0);
+
+ /* IPv6 iface-1 */
+ ha->iface_ipv6_1 = iscsi_create_iface(ha->host,
+ &qla4xxx_iscsi_transport,
+ IFACE_TYPE_IPV6, 1, 0);
+
+ /* IPv6 iface-2 */
+ ha->iface_ipv6_2 = iscsi_create_iface(ha->host,
+ &qla4xxx_iscsi_transport,
+ IFACE_TYPE_IPV6, 2, 0);
+}
+
+static void qla4xxx_destroy_iface(struct scsi_qla_host *ha)
+{
+ if (ha->iface_ipv4)
+ iscsi_destroy_iface(ha->iface_ipv4);
+ if (ha->iface_ipv6_1)
+ iscsi_destroy_iface(ha->iface_ipv6_1);
+ if (ha->iface_ipv6_2)
+ iscsi_destroy_iface(ha->iface_ipv6_2);
+}
+
/**
* qla4xxx_probe_adapter - callback function to probe HBA
* @pdev: pointer to pci_dev structure
@@ -2099,6 +2208,8 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
ha->host_no, ha->firmware_version[0], ha->firmware_version[1],
ha->patch_number, ha->build_number);
scsi_scan_host(host);
+
+ qla4xxx_create_iface(ha);
return 0;
probe_failed:
@@ -2168,6 +2279,9 @@ static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev)
/* remove devs from iscsi_sessions to scsi_devices */
qla4xxx_free_ddb_list(ha);
+ /* destroy iface from sysfs */
+ qla4xxx_destroy_iface(ha);
+
scsi_remove_host(ha->host);
qla4xxx_free_adapter(ha);
--
1.7.3.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 1/5] iscsi_transport: add support for set_net_config
2011-04-22 18:07 ` [PATCH 1/5] iscsi_transport: add support for set_net_config vikas.chaudhary
@ 2011-04-23 5:19 ` Mike Christie
0 siblings, 0 replies; 8+ messages in thread
From: Mike Christie @ 2011-04-23 5:19 UTC (permalink / raw)
To: vikas.chaudhary
Cc: James.Bottomley, linux-scsi, lalit.chandivade, ravi.anand,
Harish Zunjarrao
On 04/22/2011 01:07 PM, vikas.chaudhary@qlogic.com wrote:
> +/* 20 param per iface * 10 iface per port = 200 params */
> +#define ISCSI_MAX_IFACE_PER_HW 10
> +#define ISCSI_MAX_PARAM_PER_IFACE 20
> +#define ISCSI_MAX_NET_PARAMS (ISCSI_MAX_IFACE_PER_HW * \
> + ISCSI_MAX_PARAM_PER_IFACE)
> +
See comment from here:
http://marc.info/?l=linux-scsi&m=130266611526117&w=2
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 4/5] iscsi_transport: show network configuration in sysfs
2011-04-22 18:07 ` [PATCH 4/5] iscsi_transport: show network configuration in sysfs vikas.chaudhary
@ 2011-04-23 22:40 ` Mike Christie
0 siblings, 0 replies; 8+ messages in thread
From: Mike Christie @ 2011-04-23 22:40 UTC (permalink / raw)
To: vikas.chaudhary; +Cc: James.Bottomley, linux-scsi, lalit.chandivade, ravi.anand
On 04/22/2011 01:07 PM, vikas.chaudhary@qlogic.com wrote:
> From: Vikas Chaudhary<vikas.chaudhary@qlogic.com>
>
> To support multiple network addresses per adapter need to have a new way to
> represent network interface (net iface) in sysfs.
>
From the previous posting's comments you did not handle or respond to
the comment about linking the sessions to the iface. Basically, I want
to know how for sessionX you know which iface is being used? For
example, users want to know the src ip address for the session.
You could make a symlink from the session to the iface or make the iface
the parent of the session instead of the host then add symlinks to/from,
for compat with existing tools, the session/host.
We could do this in another patch, but I would then want to wait off on
sending this patch and the 5/5 to James so we do not have some kernels
with it and some without.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2011-04-23 22:40 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-22 18:07 [PATCH 0/5] qla4xxx: Proposal for iSCSI Network Configuration vikas.chaudhary
2011-04-22 18:07 ` [PATCH 1/5] iscsi_transport: add support for set_net_config vikas.chaudhary
2011-04-23 5:19 ` Mike Christie
2011-04-22 18:07 ` [PATCH 2/5] qla4xxx: " vikas.chaudhary
2011-04-22 18:07 ` [PATCH 3/5] qla4xxx: Added new "struct ipaddress_config" vikas.chaudhary
2011-04-22 18:07 ` [PATCH 4/5] iscsi_transport: show network configuration in sysfs vikas.chaudhary
2011-04-23 22:40 ` Mike Christie
2011-04-22 18:07 ` [PATCH 5/5] qla4xxx: added support to show multiple iface " vikas.chaudhary
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.