Add support for configuring the VLAN parameters on the adapter
 using the iscsiadm interface.

Signed-off-by: John Soni Jose <[email protected]>
Signed-off-by: Jayamohan Kallickal <[email protected]>
---
 drivers/scsi/be2iscsi/be_cmds.c  |   43 +++++++++++++++++++++
 drivers/scsi/be2iscsi/be_cmds.h  |    9 ++++
 drivers/scsi/be2iscsi/be_iscsi.c |   77 ++++++++++++++++++++++++++++++++++++++
 drivers/scsi/be2iscsi/be_mgmt.c  |   43 +++++++++++++++++++++
 drivers/scsi/be2iscsi/be_mgmt.h  |    4 ++
 5 files changed, 176 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 33f89f9..e37a85a 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -934,3 +934,46 @@ int beiscsi_cmd_reset_function(struct beiscsi_hba  *phba)
        spin_unlock(&ctrl->mbox_lock);
        return status;
 }
+
+/**
+  * be_cmd_set_vlan : Configure the VLAN parameters on the adapter
+  * @phba : the device priv structure instance
+  * vlan_value : The value to set for VLAN
+  *
+  * Set the VLAN ID/Priority for the adapter or Disable the VLAN
+  * option of the adapter. This function issues MBX Cmd for setting
+  * the values
+  *
+  * returns the tag for the Mbx Command
+  **/
+int be_cmd_set_vlan(struct beiscsi_hba *phba,
+               uint16_t vlan_value)
+{
+       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_value;
+
+       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 953c354..d6c1e2c 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_value);
+
 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 73300f1..17b0907 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -332,6 +332,52 @@ beiscsi_set_static_ip(struct Scsi_Host *shost,
        return ret;
 }
 
+/**
+  * beiscsi_set_vlan_attrib : Set the VLAN priority
+  *    @shost : Scsi_Host pointer for the function.
+  * @iface_param : Interface paramter structure.
+  *
+  * Set the VLAN value for the adapter or enable
+  * disable the VLAN option.
+  *
+  * Return
+  *    Success - 0
+  *    Failure - Non-Zero value
+  *
+  **/
+static int
+beiscsi_set_vlan_attrib(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 +414,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_attrib(shost, iface_param);
+               break;
        default:
                beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
                                "BS_%d : Param %d not supported\n",
@@ -489,6 +539,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)
+                       len = sprintf(buf, "\n");
+               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)
+                       len = sprintf(buf, "\n");
+               else
+                       len = sprintf(buf, "%d\n",
+                                       ((if_info.vlan_priority >> 13) &
+                                        ISCSI_MAX_VLAN_PRIORITY));
+               break;
        default:
                WARN_ON(1);
        }
@@ -510,6 +581,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 +1307,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 c97a814..790629a 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -1092,3 +1092,46 @@ int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
                        "BG_%d : Login to Boot Target Failed\n");
        return -ENXIO;
 }
+
+/**
+  * mgmt_set_vlan : Wait for the Mbox completion
+  * @phba : device private structure
+  * @vlan_value : the VLAN value to be set
+  *
+  * Returns
+  *            Success : 0
+  *            Failure : Non-Zero Value
+  **/
+int mgmt_set_vlan(struct beiscsi_hba *phba,
+               uint16_t vlan_value)
+{
+       unsigned int tag, wrb_num;
+       unsigned short status, extd_status;
+
+       tag = be_cmd_set_vlan(phba, vlan_value);
+       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 cd97e70..f5b0074 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.h
+++ b/drivers/scsi/be2iscsi/be_mgmt.h
@@ -295,4 +295,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_value);
 #endif
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to