Skip to content

Commit

Permalink
[SCSI] be2iscsi: Add support for configuring the VLAN on the adapter.
Browse files Browse the repository at this point in the history
Add support for configuring the VLAN parameters on the adapter
using the iscsiadm interface.

Signed-off-by: John Soni Jose <sony.john-n@emulex.com>
Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
  • Loading branch information
John Soni Jose authored and James Bottomley committed Sep 14, 2012
1 parent df5d0e6 commit 6f72238
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 0 deletions.
42 changes: 42 additions & 0 deletions drivers/scsi/be2iscsi/be_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
9 changes: 9 additions & 0 deletions drivers/scsi/be2iscsi/be_cmds.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
76 changes: 76 additions & 0 deletions drivers/scsi/be2iscsi/be_iscsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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);
}
Expand All @@ -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:
Expand Down Expand Up @@ -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;
Expand Down
46 changes: 46 additions & 0 deletions drivers/scsi/be2iscsi/be_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
4 changes: 4 additions & 0 deletions drivers/scsi/be2iscsi/be_mgmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 6f72238

Please sign in to comment.