Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f72238e authored by John Soni Jose's avatar John Soni Jose Committed by James Bottomley
Browse files

[SCSI] be2iscsi: Add support for configuring the VLAN on the adapter.



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

Signed-off-by: default avatarJohn Soni Jose <sony.john-n@emulex.com>
Signed-off-by: default avatarJayamohan Kallickal <jayamohan.kallickal@emulex.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent df5d0e6e
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
@@ -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;
+76 −0
Original line number Diff line number Diff line
@@ -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;
+46 −0
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
@@ -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