aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.c42
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.h9
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.c76
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c46
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.h4
5 files changed, 177 insertions, 0 deletions
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index d0058e38bc62..07d2cb126d93 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -934,3 +934,45 @@ int beiscsi_cmd_reset_function(struct beiscsi_hba *phba)
spin_unlock(&ctrl->mbox_lock);
return status;
}
+
+/**
+ * be_cmd_set_vlan()- Configure VLAN paramters on the adapter
+ * @phba: device priv structure instance
+ * @vlan_tag: TAG to be set
+ *
+ * Set the VLAN_TAG for the adapter or Disable VLAN on adapter
+ *
+ * returns
+ * TAG for the MBX Cmd
+ * **/
+int be_cmd_set_vlan(struct beiscsi_hba *phba,
+ uint16_t vlan_tag)
+{
+ unsigned int tag = 0;
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_set_vlan_req *req;
+ struct be_ctrl_info *ctrl = &phba->ctrl;
+
+ spin_lock(&ctrl->mbox_lock);
+ tag = alloc_mcc_tag(phba);
+ if (!tag) {
+ spin_unlock(&ctrl->mbox_lock);
+ return tag;
+ }
+
+ wrb = wrb_from_mccq(phba);
+ req = embedded_payload(wrb);
+ wrb->tag0 |= tag;
+ be_wrb_hdr_prepare(wrb, sizeof(*wrb), true, 0);
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
+ OPCODE_COMMON_ISCSI_NTWK_SET_VLAN,
+ sizeof(*req));
+
+ req->interface_hndl = phba->interface_handle;
+ req->vlan_priority = vlan_tag;
+
+ be_mcc_notify(phba);
+ spin_unlock(&ctrl->mbox_lock);
+
+ return tag;
+}
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index 953c354c4d97..2c8f98df1287 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -449,6 +449,12 @@ struct be_cmd_get_def_gateway_resp {
struct ip_addr_format ip_addr;
} __packed;
+#define BEISCSI_VLAN_DISABLE 0xFFFF
+struct be_cmd_set_vlan_req {
+ struct be_cmd_req_hdr hdr;
+ u32 interface_hndl;
+ u32 vlan_priority;
+} __packed;
/******************** Create CQ ***************************/
/**
* Pseudo amap definition in which each bit of the actual structure is defined
@@ -688,6 +694,9 @@ int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem,
bool is_link_state_evt(u32 trailer);
+/* Configuration Functions */
+int be_cmd_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag);
+
struct be_default_pdu_context {
u32 dw[4];
} __packed;
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index 8efdd8e2d989..ebb6c1fc1607 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -332,6 +332,51 @@ beiscsi_set_static_ip(struct Scsi_Host *shost,
return ret;
}
+/**
+ * beiscsi_set_vlan_tag()- Set the VLAN TAG
+ * @shost: Scsi Host for the driver instance
+ * @iface_param: Interface paramters
+ *
+ * Set the VLAN TAG for the adapter or disable
+ * the VLAN config
+ *
+ * returns
+ * Success: 0
+ * Failure: Non-Zero Value
+ **/
+static int
+beiscsi_set_vlan_tag(struct Scsi_Host *shost,
+ struct iscsi_iface_param_info *iface_param)
+{
+ struct beiscsi_hba *phba = iscsi_host_priv(shost);
+ int ret = 0;
+
+ /* Get the Interface Handle */
+ if (mgmt_get_all_if_id(phba)) {
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : Getting Interface Handle Failed\n");
+ return -EIO;
+ }
+
+ switch (iface_param->param) {
+ case ISCSI_NET_PARAM_VLAN_ENABLED:
+ if (iface_param->value[0] != ISCSI_VLAN_ENABLE)
+ ret = mgmt_set_vlan(phba, BEISCSI_VLAN_DISABLE);
+ break;
+ case ISCSI_NET_PARAM_VLAN_TAG:
+ ret = mgmt_set_vlan(phba,
+ *((uint16_t *)iface_param->value));
+ break;
+ default:
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+ "BS_%d : Unkown Param Type : %d\n",
+ iface_param->param);
+ return -ENOSYS;
+ }
+ return ret;
+}
+
+
static int
beiscsi_set_ipv4(struct Scsi_Host *shost,
struct iscsi_iface_param_info *iface_param,
@@ -368,6 +413,10 @@ beiscsi_set_ipv4(struct Scsi_Host *shost,
ret = beiscsi_set_static_ip(shost, iface_param,
data, dt_len);
break;
+ case ISCSI_NET_PARAM_VLAN_ENABLED:
+ case ISCSI_NET_PARAM_VLAN_TAG:
+ ret = beiscsi_set_vlan_tag(shost, iface_param);
+ break;
default:
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
"BS_%d : Param %d not supported\n",
@@ -489,6 +538,27 @@ static int be2iscsi_get_if_param(struct beiscsi_hba *phba,
case ISCSI_NET_PARAM_IPV4_SUBNET:
len = sprintf(buf, "%pI4\n", &if_info.ip_addr.subnet_mask);
break;
+ case ISCSI_NET_PARAM_VLAN_ENABLED:
+ len = sprintf(buf, "%s\n",
+ (if_info.vlan_priority == BEISCSI_VLAN_DISABLE)
+ ? "Disabled" : "Enabled");
+ break;
+ case ISCSI_NET_PARAM_VLAN_ID:
+ if (if_info.vlan_priority == BEISCSI_VLAN_DISABLE)
+ return -EINVAL;
+ else
+ len = sprintf(buf, "%d\n",
+ (if_info.vlan_priority &
+ ISCSI_MAX_VLAN_ID));
+ break;
+ case ISCSI_NET_PARAM_VLAN_PRIORITY:
+ if (if_info.vlan_priority == BEISCSI_VLAN_DISABLE)
+ return -EINVAL;
+ else
+ len = sprintf(buf, "%d\n",
+ ((if_info.vlan_priority >> 13) &
+ ISCSI_MAX_VLAN_PRIORITY));
+ break;
default:
WARN_ON(1);
}
@@ -510,6 +580,9 @@ int be2iscsi_iface_get_param(struct iscsi_iface *iface,
case ISCSI_NET_PARAM_IPV4_SUBNET:
case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
case ISCSI_NET_PARAM_IPV6_ADDR:
+ case ISCSI_NET_PARAM_VLAN_ENABLED:
+ case ISCSI_NET_PARAM_VLAN_ID:
+ case ISCSI_NET_PARAM_VLAN_PRIORITY:
len = be2iscsi_get_if_param(phba, iface, param, buf);
break;
case ISCSI_NET_PARAM_IFACE_ENABLE:
@@ -1233,6 +1306,9 @@ umode_t be2iscsi_attr_is_visible(int param_type, int param)
case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
case ISCSI_NET_PARAM_IPV4_GW:
case ISCSI_NET_PARAM_IPV6_ADDR:
+ case ISCSI_NET_PARAM_VLAN_ID:
+ case ISCSI_NET_PARAM_VLAN_PRIORITY:
+ case ISCSI_NET_PARAM_VLAN_ENABLED:
return S_IRUGO;
default:
return 0;
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 3dca332acce2..aab5dd359e2c 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -1090,3 +1090,49 @@ int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
"BG_%d : Login to Boot Target Failed\n");
return -ENXIO;
}
+
+/**
+ * mgmt_set_vlan()- Issue and wait for CMD completion
+ * @phba: device private structure instance
+ * @vlan_tag: VLAN tag
+ *
+ * Issue the MBX Cmd and wait for the completion of the
+ * command.
+ *
+ * returns
+ * Success: 0
+ * Failure: Non-Xero Value
+ **/
+int mgmt_set_vlan(struct beiscsi_hba *phba,
+ uint16_t vlan_tag)
+{
+ unsigned int tag, wrb_num;
+ unsigned short status, extd_status;
+
+ tag = be_cmd_set_vlan(phba, vlan_tag);
+ if (!tag) {
+ beiscsi_log(phba, KERN_ERR,
+ (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
+ "BG_%d : VLAN Setting Failed\n");
+ return -EBUSY;
+ } else
+ wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+ phba->ctrl.mcc_numtag[tag]);
+
+ wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
+ extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
+ status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
+
+ if (status || extd_status) {
+ beiscsi_log(phba, KERN_ERR,
+ (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
+ "BS_%d : status : %d extd_status : %d\n",
+ status, extd_status);
+
+ free_mcc_tag(&phba->ctrl, tag);
+ return -EAGAIN;
+ }
+
+ free_mcc_tag(&phba->ctrl, tag);
+ return 0;
+}
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h
index 63b8e81f3250..1bbac5c69da2 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.h
+++ b/drivers/scsi/be2iscsi/be_mgmt.h
@@ -296,4 +296,8 @@ int mgmt_set_gateway(struct beiscsi_hba *phba,
int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
unsigned int *s_handle);
+
+unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba);
+
+int mgmt_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag);
#endif