[ewg] [PATCH 2/10 VNIC] Changes to VNIC control state machine

Ramachandra K ramachandra.kuchimanchi at qlogic.com
Tue Aug 21 07:23:19 PDT 2007


Reimplement control statemachine for fixing IB send not completed errors.
Also simplify the control command processing logic and remove all control QP retries.

From: Poornima Kamath <poornima.kamath at qlogic.com>
Signed-off-by: Ramachandra K <ramachandra.kuchimanchi at qlogic.com>
---

 drivers/infiniband/ulp/vnic/vnic_config.c      |    1 
 drivers/infiniband/ulp/vnic/vnic_config.h      |    2 
 drivers/infiniband/ulp/vnic/vnic_control.c     |  388 +++++++++++++++---------
 drivers/infiniband/ulp/vnic/vnic_control.h     |   39 ++
 drivers/infiniband/ulp/vnic/vnic_control_pkt.h |    1 
 5 files changed, 282 insertions(+), 149 deletions(-)

diff --git a/drivers/infiniband/ulp/vnic/vnic_config.c b/drivers/infiniband/ulp/vnic/vnic_config.c
index d3b02d4..0447427 100644
--- a/drivers/infiniband/ulp/vnic/vnic_config.c
+++ b/drivers/infiniband/ulp/vnic/vnic_config.c
@@ -133,7 +133,6 @@ static void config_control_defaults(stru
 	control_config->vnic_instance = params->instance;
 	control_config->max_address_entries = MAX_ADDRESS_ENTRIES;
 	control_config->min_address_entries = MIN_ADDRESS_ENTRIES;
-	control_config->req_retry_count = CONTROL_REQ_RETRY_COUNT;
 	control_config->rsp_timeout = msecs_to_jiffies(CONTROL_RSP_TIMEOUT);
 }
 
diff --git a/drivers/infiniband/ulp/vnic/vnic_config.h b/drivers/infiniband/ulp/vnic/vnic_config.h
index f9850e7..03cbf9c 100644
--- a/drivers/infiniband/ulp/vnic/vnic_config.h
+++ b/drivers/infiniband/ulp/vnic/vnic_config.h
@@ -120,7 +120,6 @@ enum {
 #define VNIC_USE_RX_CSUM		1
 #define VNIC_USE_TX_CSUM		1
 #define	DEFAULT_PREFER_PRIMARY		0
-#define	CONTROL_REQ_RETRY_COUNT		4
 
 struct path_param {
 	__be64			ioc_guid;
@@ -155,7 +154,6 @@ struct control_config {
 	u16			max_address_entries;
 	u16			min_address_entries;
 	u32			rsp_timeout;
-	u8			req_retry_count;
 };
 
 struct data_config {
diff --git a/drivers/infiniband/ulp/vnic/vnic_control.c b/drivers/infiniband/ulp/vnic/vnic_control.c
index 02e8fa5..5d582db 100644
--- a/drivers/infiniband/ulp/vnic/vnic_control.c
+++ b/drivers/infiniband/ulp/vnic/vnic_control.c
@@ -75,8 +75,8 @@ static void control_recv_complete(struct
 	unsigned long			flags;
 	cycles_t			response_time;
 
-	CONTROL_FUNCTION("%s: control_recv_complete()\n",
-			 control_ifcfg_name(control));
+	CONTROL_FUNCTION("%s: control_recv_complete() State=%d\n",
+			 control_ifcfg_name(control), control->req_state);
 
 	ib_dma_sync_single_for_cpu(control->parent->config->ibdev,
 				   control->recv_dma, control->recv_len,
@@ -92,18 +92,67 @@ static void control_recv_complete(struct
 		if (last_recv_io)
 			control_recv(control, last_recv_io);
 	} else if (c_hdr->pkt_type == TYPE_RSP) {
-		if (control->rsp_expected
-		    && (c_hdr->pkt_seq_num == control->seq_num)) {
-			control->response = recv_io;
-			control->rsp_expected = 0;
-			spin_unlock_irqrestore(&control->io_lock, flags);
-			control_update_rsptime_stats(control,
-						     response_time);
+		u8 repost = 0;
+		u8 fail = 0;
+		u8 kick = 0;
+
+		switch (control->req_state) {
+		case REQ_INACTIVE:
+		case RSP_RECEIVED:
+		case REQ_COMPLETED:
+			CONTROL_ERROR("%s: Unexpected control"
+				      "response received: CMD = %d\n",
+				      control_ifcfg_name(control), c_hdr->pkt_cmd);
+			control_log_control_packet(pkt);
+			control->req_state = REQ_FAILED;
+			fail = 1;
+			break;
+		case REQ_POSTED:
+		case REQ_SENT:
+			if (c_hdr->pkt_cmd != control->last_cmd
+				|| c_hdr->pkt_seq_num != control->seq_num) {
+				CONTROL_ERROR("%s: Incorrect Control Response"
+					      "received\n",
+					      control_ifcfg_name(control));
+				CONTROL_ERROR("%s: Sent control request:\n",
+					      control_ifcfg_name(control));
+				control_log_control_packet(control_last_req(control));
+				CONTROL_ERROR("%s: Received control response:\n",
+					      control_ifcfg_name(control));
+				control_log_control_packet(pkt);
+				control->req_state = REQ_FAILED;
+				fail = 1;
+			} else {
+				control->response = recv_io;
+				control_update_rsptime_stats(control,
+							    response_time);
+				if (control->req_state == REQ_POSTED) {
+					CONTROL_INFO("%s: Recv CMD RSP %d"
+						     "before Send Completion\n",
+						     control_ifcfg_name(control),
+						     c_hdr->pkt_cmd);
+					control->req_state = RSP_RECEIVED;
+				} else {
+					control->req_state = REQ_COMPLETED;
+					kick = 1;
+				}
+			}
+			break;
+		case REQ_FAILED:
+			/* stay in REQ_FAILED state */
+			repost = 1;
+			break;
+		}
+		spin_unlock_irqrestore(&control->io_lock, flags);
+		/* we must do this outside the lock*/
+		if (kick)
 			viport_kick(control->parent);
-		} else {
-			spin_unlock_irqrestore(&control->io_lock, flags);
+		if (repost || fail) {
 			control_recv(control, recv_io);
+			if (fail)
+				viport_failure(control->parent);
 		}
+
 	} else {
 		list_add_tail(&recv_io->io.list_ptrs,
 			      &control->failure_list);
@@ -118,13 +167,52 @@ static void control_recv_complete(struct
 static void control_timeout(unsigned long data)
 {
 	struct control *control;
+	unsigned long 		  flags;
+	u8 fail = 0;
+	u8 kick = 0;
 
 	control = (struct control *)data;
-	CONTROL_FUNCTION("%s: control_timeout()\n",
-			 control_ifcfg_name(control));
+	CONTROL_FUNCTION("%s: control_timeout(), State=%d\n",
+			 control_ifcfg_name(control), control->req_state);
 	control->timer_state = TIMER_EXPIRED;
-	control->rsp_expected = 0;
-	viport_kick(control->parent);
+
+	spin_lock_irqsave(&control->io_lock, flags);
+	switch (control->req_state) {
+	case REQ_INACTIVE:
+		kick = 1;
+		/* stay in REQ_INACTIVE state */
+		break;
+	case REQ_POSTED:
+	case REQ_SENT:
+		control->req_state = REQ_FAILED;
+		CONTROL_ERROR("%s: No send Completion for Cmd=%d \n",
+			      control_ifcfg_name(control), control->last_cmd);
+		control_timeout_stats(control);
+		fail = 1;
+		break;
+	case RSP_RECEIVED:
+		control->req_state = REQ_FAILED;
+		CONTROL_ERROR("%s: No response received from EIOC for Cmd=%d\n",
+			      control_ifcfg_name(control), control->last_cmd);
+		control_timeout_stats(control);
+		fail = 1;
+		break;
+	case REQ_COMPLETED:
+		/* stay in REQ_COMPLETED state*/
+		kick = 1;
+		break;
+	case REQ_FAILED:
+		/* stay in REQ_FAILED state*/
+		break;
+	}
+	spin_unlock_irqrestore(&control->io_lock, flags);
+	/* we must do this outside the lock */
+	if (fail)
+		viport_failure(control->parent);
+	if (kick)
+		viport_kick(control->parent);
+
+	return;
 }
 
 static void control_timer(struct control *control, int timeout)
@@ -155,37 +243,100 @@ static void control_timer_stop(struct co
 
 static int control_send(struct control *control, struct send_io *send_io)
 {
-	CONTROL_FUNCTION("%s: control_send()\n",
-			 control_ifcfg_name(control));
-	if (control->req_outstanding) {
-		CONTROL_ERROR("%s: IB send never completed\n",
-			      control_ifcfg_name(control));
-		goto out;
-	}
+	unsigned long 	flags;
+	u8 ret = -1;
+	u8 fail = 0;
+	struct vnic_control_packet *pkt = control_packet(send_io);
 
-	control->req_outstanding = 1;
-	control_timer(control, control->config->rsp_timeout);
-	control_note_reqtime_stats(control);
-	if (vnic_ib_post_send(&control->ib_conn, &control->send_io.io)) {
-		CONTROL_ERROR("failed to post send\n");
-		control->req_outstanding = 0;
-		goto out;
+	CONTROL_FUNCTION("%s: control_send(), State=%d\n",
+			 control_ifcfg_name(control), control->req_state);
+	spin_lock_irqsave(&control->io_lock, flags);
+	switch (control->req_state) {
+	case REQ_INACTIVE:
+		CONTROL_PACKET(pkt);
+		control_timer(control, control->config->rsp_timeout);
+		control_note_reqtime_stats(control);
+		if (vnic_ib_post_send(&control->ib_conn, &control->send_io.io)) {
+			CONTROL_ERROR("%s: Failed to post send\n",
+				control_ifcfg_name(control));
+			/* stay in REQ_INACTIVE state*/
+			fail = 1;
+		} else {
+			control->last_cmd = pkt->hdr.pkt_cmd;
+			control->req_state = REQ_POSTED;
+			ret = 0;
+		}
+		break;
+	case REQ_POSTED:
+	case REQ_SENT:
+	case RSP_RECEIVED:
+	case REQ_COMPLETED:
+		CONTROL_ERROR("%s:Previous Command is not completed."
+			      "New CMD: %d Last CMD: %d Seq: %d\n",
+			      control_ifcfg_name(control), pkt->hdr.pkt_cmd,
+			      control->last_cmd, control->seq_num);
+
+		control->req_state = REQ_FAILED;
+		fail = 1;
+		break;
+	case REQ_FAILED:
+		/* this can occur after an error when ViPort state machine
+		 * attempts to reset the link.
+		 */
+		CONTROL_INFO("%s:Attempt to send in failed state."
+			     "New CMD: %d Last CMD: %d\n",
+			     control_ifcfg_name(control), pkt->hdr.pkt_cmd,
+			     control->last_cmd );
+		/* stay in REQ_FAILED state*/
+		break;
 	}
+	spin_unlock_irqrestore(&control->io_lock, flags);
 
-	return 0;
-out:
-	viport_failure(control->parent);
-	return -1;
+	/* we must do this outside the lock */
+	if (fail)
+		viport_failure(control->parent);
+	return ret;
 
 }
 
 static void control_send_complete(struct io *io)
 {
 	struct control *control = &io->viport->control;
+	unsigned long 		  flags;
+	u8 fail = 0;
+	u8 kick = 0;
 
-	CONTROL_FUNCTION("%s: control_send_complete()\n",
-			 control_ifcfg_name(control));
-	control->req_outstanding = 0;
+	CONTROL_FUNCTION("%s: control_sendComplete(), State=%d\n",
+			 control_ifcfg_name(control), control->req_state);
+	spin_lock_irqsave(&control->io_lock, flags);
+	switch (control->req_state) {
+	case REQ_INACTIVE:
+	case REQ_SENT:
+	case REQ_COMPLETED:
+		CONTROL_ERROR("%s: Unexpected control send completion\n",
+			      control_ifcfg_name(control));
+		fail = 1;
+		control->req_state = REQ_FAILED;
+		break;
+	case REQ_POSTED:
+		control->req_state = REQ_SENT;
+		break;
+	case RSP_RECEIVED:
+		control->req_state = REQ_COMPLETED;
+		kick = 1;
+		break;
+	case REQ_FAILED:
+		/* stay in REQ_FAILED state */
+		break;
+	}
+	spin_unlock_irqrestore(&control->io_lock, flags);
+	/* we must do this outside the lock */
+	if (fail)
+		viport_failure(control->parent);
+	if (kick)
+		viport_kick(control->parent);
+
+	return;
 }
 
 void control_process_async(struct control *control)
@@ -286,51 +437,55 @@ static struct send_io *control_init_hdr(
 	hdr->pkt_cmd = cmd;
 	control->seq_num++;
 	hdr->pkt_seq_num = control->seq_num;
-	control->req_retry_counter = 0;
-	hdr->pkt_retry_count = control->req_retry_counter;
+	hdr->pkt_retry_count = 0;
 
 	return &control->send_io;
 }
 
 static struct recv_io *control_get_rsp(struct control *control)
 {
-	struct recv_io	*recv_io;
+	struct recv_io	*recv_io = NULL;
 	unsigned long	flags;
+	u8 fail = 0;
 
-	CONTROL_FUNCTION("%s: control_get_rsp()\n",
-			 control_ifcfg_name(control));
+	CONTROL_FUNCTION("%s: control_getRsp(), State=%d\n",
+			 control_ifcfg_name(control), control->req_state);
 	spin_lock_irqsave(&control->io_lock, flags);
-	recv_io = control->response;
-	if (recv_io) {
-		control_timer_stop(control);
-		control->response = NULL;
-		spin_unlock_irqrestore(&control->io_lock, flags);
-		return recv_io;
-	}
-	spin_unlock_irqrestore(&control->io_lock, flags);
-	if (control->timer_state == TIMER_EXPIRED) {
-		struct vnic_control_packet *pkt =
-		    control_packet(&control->send_io);
-		struct vnic_control_header *hdr = &pkt->hdr;
-
-		control->timer_state = TIMER_IDLE;
-		CONTROL_ERROR("%s: no response received from EIOC\n",
+	switch (control->req_state) {
+	case REQ_INACTIVE:
+		CONTROL_ERROR("%s: Checked for Response with no"
+			      "command pending\n",
 			      control_ifcfg_name(control));
-		control_timeout_stats(control);
-		control->req_retry_counter++;
-		if (control->req_retry_counter >=
-		    control->config->req_retry_count) {
-			CONTROL_ERROR("%s: control packet retry exceeded\n",
-				      control_ifcfg_name(control));
-			viport_failure(control->parent);
-		} else {
-			hdr->pkt_retry_count =
-			    control->req_retry_counter;
-			control_send(control, &control->send_io);
+		control->req_state = REQ_FAILED;
+		fail = 1;
+		break;
+	case REQ_POSTED:
+	case REQ_SENT:
+	case RSP_RECEIVED:
+		/* no response available yet
+		 stay in present state*/
+		break;
+	case REQ_COMPLETED:
+		recv_io = control->response;
+		if (!recv_io){
+			control->req_state = REQ_FAILED;
+			fail = 1;
+			break;
 		}
+		control->response = NULL;
+		control->last_cmd = CMD_INVALID;
+		control_timer_stop(control);
+		control->req_state = REQ_INACTIVE;
+		break;
+	case REQ_FAILED:
+		control_timer_stop(control);
+		/* stay in REQ_FAILED state*/
+		break;
 	}
-
-	return NULL;
+	spin_unlock_irqrestore(&control->io_lock, flags);
+	if (fail)
+		viport_failure(control->parent);
+	return recv_io;
 }
 
 int control_init_vnic_req(struct control *control)
@@ -359,10 +514,9 @@ int control_init_vnic_req(struct control
 	init_vnic_req->num_address_entries =
 				cpu_to_be16(config->max_address_entries);
 
+	control->last_cmd = pkt->hdr.pkt_cmd;
 	CONTROL_PACKET(pkt);
 
-	control->rsp_expected = pkt->hdr.pkt_cmd;
-
 	ib_dma_sync_single_for_device(control->parent->config->ibdev,
 				      control->send_dma, control->send_len,
 				      DMA_TO_DEVICE);
@@ -443,15 +597,8 @@ int control_init_vnic_rsp(struct control
 		goto out;
 
 	pkt = control_packet(recv_io);
-	if (pkt->hdr.pkt_cmd != CMD_INIT_VNIC) {
-		CONTROL_ERROR("%s: sent control request:\n",
-			      control_ifcfg_name(control));
-		control_log_control_packet(control_last_req(control));
-		CONTROL_ERROR("%s: received control response:\n",
-			      control_ifcfg_name(control));
-		control_log_control_packet(pkt);
+	if (pkt->hdr.pkt_cmd != CMD_INIT_VNIC)
 		goto failure;
-	}
 
 	init_vnic_rsp = &pkt->cmd.init_vnic_rsp;
 	control->maj_ver = be16_to_cpu(init_vnic_rsp->vnic_major_version);
@@ -640,7 +787,7 @@ int control_config_data_path_req(struct
 			      &config_data_path->eioc_recv_pool_config);
 	CONTROL_PACKET(pkt);
 
-	control->rsp_expected = pkt->hdr.pkt_cmd;
+	control->last_cmd = pkt->hdr.pkt_cmd;
 
 	ib_dma_sync_single_for_device(control->parent->config->ibdev,
 				      control->send_dma, control->send_len,
@@ -677,15 +824,8 @@ int control_config_data_path_rsp(struct
 		goto out;
 
 	pkt = control_packet(recv_io);
-	if (pkt->hdr.pkt_cmd != CMD_CONFIG_DATA_PATH) {
-		CONTROL_ERROR("%s: sent control request:\n",
-			      control_ifcfg_name(control));
-		control_log_control_packet(control_last_req(control));
-		CONTROL_ERROR("%s: received control response:\n",
-			      control_ifcfg_name(control));
-		control_log_control_packet(pkt);
+	if (pkt->hdr.pkt_cmd != CMD_CONFIG_DATA_PATH)
 		goto failure;
-	}
 
 	config_data_path = &pkt->cmd.config_data_path_rsp;
 	if (config_data_path->data_path != 0) {
@@ -742,7 +882,7 @@ int control_exchange_pools_req(struct co
 	exchange_pools->pool_rkey = cpu_to_be32(rkey);
 	exchange_pools->pool_addr = cpu_to_be64(addr);
 
-	control->rsp_expected = pkt->hdr.pkt_cmd;
+	control->last_cmd = pkt->hdr.pkt_cmd;
 
 	ib_dma_sync_single_for_device(control->parent->config->ibdev,
 				      control->send_dma, control->send_len,
@@ -773,15 +913,8 @@ int control_exchange_pools_rsp(struct co
 		goto out;
 
 	pkt = control_packet(recv_io);
-	if (pkt->hdr.pkt_cmd != CMD_EXCHANGE_POOLS) {
-		CONTROL_ERROR("%s: sent control request:\n",
-			      control_ifcfg_name(control));
-		control_log_control_packet(control_last_req(control));
-		CONTROL_ERROR("%s: received control response:\n",
-			      control_ifcfg_name(control));
-		control_log_control_packet(pkt);
+	if (pkt->hdr.pkt_cmd != CMD_EXCHANGE_POOLS)
 		goto failure;
-	}
 
 	exchange_pools = &pkt->cmd.exchange_pools_rsp;
 	*rkey = be32_to_cpu(exchange_pools->pool_rkey);
@@ -852,7 +985,7 @@ int control_config_link_req(struct contr
 
 	config_link_req->mtu_size = cpu_to_be16(mtu);
 
-	control->rsp_expected = pkt->hdr.pkt_cmd;
+	control->last_cmd = pkt->hdr.pkt_cmd;
 	ib_dma_sync_single_for_device(control->parent->config->ibdev,
 				      control->send_dma, control->send_len,
 				      DMA_TO_DEVICE);
@@ -882,15 +1015,8 @@ int control_config_link_rsp(struct contr
 		goto out;
 
 	pkt = control_packet(recv_io);
-	if (pkt->hdr.pkt_cmd != CMD_CONFIG_LINK) {
-		CONTROL_ERROR("%s: sent control request:\n",
-			      control_ifcfg_name(control));
-		control_log_control_packet(control_last_req(control));
-		CONTROL_ERROR("%s: received control response:\n",
-			      control_ifcfg_name(control));
-		control_log_control_packet(pkt);
+	if (pkt->hdr.pkt_cmd != CMD_CONFIG_LINK)
 		goto failure;
-	}
 	config_link_rsp = &pkt->cmd.config_link_rsp;
 	if (config_link_rsp->cmd_flags & VNIC_FLAG_ENABLE_NIC)
 		*flags |= IFF_UP;
@@ -967,7 +1093,7 @@ int control_config_addrs_req(struct cont
 	}
 	config_addrs_req->num_address_ops = j;
 
-	control->rsp_expected = pkt->hdr.pkt_cmd;
+	control->last_cmd = pkt->hdr.pkt_cmd;
 	ib_dma_sync_single_for_device(control->parent->config->ibdev,
 				      control->send_dma, control->send_len,
 				      DMA_TO_DEVICE);
@@ -999,15 +1125,8 @@ int control_config_addrs_rsp(struct cont
 		goto out;
 
 	pkt = control_packet(recv_io);
-	if (pkt->hdr.pkt_cmd != CMD_CONFIG_ADDRESSES) {
-		CONTROL_ERROR("%s: sent control request:\n",
-			      control_ifcfg_name(control));
-		control_log_control_packet(control_last_req(control));
-		CONTROL_ERROR("%s: received control response:\n",
-			      control_ifcfg_name(control));
-		control_log_control_packet(pkt);
+	if (pkt->hdr.pkt_cmd != CMD_CONFIG_ADDRESSES)
 		goto failure;
-	}
 	config_addrs_rsp = &pkt->cmd.config_addresses_rsp;
 
 	control_recv(control, recv_io);
@@ -1045,7 +1164,7 @@ int control_report_statistics_req(struct
 	report_statistics_req->lan_switch_num =
 	    control->lan_switch.lan_switch_num;
 
-	control->rsp_expected = pkt->hdr.pkt_cmd;
+	control->last_cmd = pkt->hdr.pkt_cmd;
 	ib_dma_sync_single_for_device(control->parent->config->ibdev,
 				      control->send_dma, control->send_len,
 				      DMA_TO_DEVICE);
@@ -1075,15 +1194,8 @@ int control_report_statistics_rsp(struct
 		goto out;
 
 	pkt = control_packet(recv_io);
-	if (pkt->hdr.pkt_cmd != CMD_REPORT_STATISTICS) {
-		CONTROL_ERROR("%s: sent control request:\n",
-			      control_ifcfg_name(control));
-		control_log_control_packet(control_last_req(control));
-		CONTROL_ERROR("%s: received control response:\n",
-			      control_ifcfg_name(control));
-		control_log_control_packet(pkt);
+	if (pkt->hdr.pkt_cmd != CMD_REPORT_STATISTICS)
 		goto failure;
-	}
 
 	rep_stat_rsp = &pkt->cmd.report_statistics_rsp;
 
@@ -1142,7 +1254,7 @@ int control_reset_req(struct control * c
 
 	pkt = control_packet(send_io);
 
-	control->rsp_expected = pkt->hdr.pkt_cmd;
+	control->last_cmd = pkt->hdr.pkt_cmd;
 	ib_dma_sync_single_for_device(control->parent->config->ibdev,
 				      control->send_dma, control->send_len,
 				      DMA_TO_DEVICE);
@@ -1170,15 +1282,8 @@ int control_reset_rsp(struct control * c
 		goto out;
 
 	pkt = control_packet(recv_io);
-	if (pkt->hdr.pkt_cmd != CMD_RESET) {
-		CONTROL_ERROR("%s: sent control request:\n",
-			      control_ifcfg_name(control));
-		control_log_control_packet(control_last_req(control));
-		CONTROL_ERROR("%s: received control response:\n",
-			      control_ifcfg_name(control));
-		control_log_control_packet(pkt);
+	if (pkt->hdr.pkt_cmd != CMD_RESET)
 		goto failure;
-	}
 
 	control_recv(control, recv_io);
 	ib_dma_sync_single_for_device(control->parent->config->ibdev,
@@ -1214,7 +1319,7 @@ int control_heartbeat_req(struct control
 	heartbeat_req = &pkt->cmd.heartbeat_req;
 	heartbeat_req->hb_interval = cpu_to_be32(hb_interval);
 
-	control->rsp_expected = pkt->hdr.pkt_cmd;
+	control->last_cmd = pkt->hdr.pkt_cmd;
 	ib_dma_sync_single_for_device(control->parent->config->ibdev,
 				      control->send_dma, control->send_len,
 				      DMA_TO_DEVICE);
@@ -1243,15 +1348,8 @@ int control_heartbeat_rsp(struct control
 		goto out;
 
 	pkt = control_packet(recv_io);
-	if (pkt->hdr.pkt_cmd != CMD_HEARTBEAT) {
-		CONTROL_ERROR("%s: sent control request:\n",
-			      control_ifcfg_name(control));
-		control_log_control_packet(control_last_req(control));
-		CONTROL_ERROR("%s: received control response:\n",
-			      control_ifcfg_name(control));
-		control_log_control_packet(pkt);
+	if (pkt->hdr.pkt_cmd != CMD_HEARTBEAT)
 		goto failure;
-	}
 
 	heartbeat_rsp = &pkt->cmd.heartbeat_rsp;
 
@@ -1371,7 +1469,8 @@ int control_init(struct control * contro
 	control->ib_conn.viport = viport;
 	control->ib_conn.ib_config = &config->ib_config;
 	control->ib_conn.state = IB_CONN_UNINITTED;
-	control->req_outstanding = 0;
+	control->req_state = REQ_INACTIVE;
+	control->last_cmd  = CMD_INVALID;
 	control->seq_num = 0;
 	control->response = NULL;
 	control->info = NULL;
@@ -1456,6 +1555,9 @@ void control_cleanup(struct control *con
 		printk(KERN_DEBUG "control CM DREQ sending failed\n");
 
 	control_timer_stop(control);
+	control->req_state  = REQ_INACTIVE;
+	control->response   = NULL;
+	control->last_cmd   = CMD_INVALID;
 	ib_destroy_cm_id(control->ib_conn.cm_id);
 	ib_destroy_qp(control->ib_conn.qp);
 	ib_destroy_cq(control->ib_conn.cq);
diff --git a/drivers/infiniband/ulp/vnic/vnic_control.h b/drivers/infiniband/ulp/vnic/vnic_control.h
index 9dfc741..2f3932b 100644
--- a/drivers/infiniband/ulp/vnic/vnic_control.h
+++ b/drivers/infiniband/ulp/vnic/vnic_control.h
@@ -47,6 +47,40 @@ enum control_timer_state {
 	TIMER_EXPIRED	= 2
 };
 
+enum control_request_state {
+	REQ_INACTIVE, /* quiet state, all previous operations done
+              *      response is NULL
+              *      last_cmd = CMD_INVALID
+              *      timer_state = IDLE
+                          */
+	REQ_POSTED, /* REQ put on send Q
+              *      response is NULL
+              *      last_cmd = command issued
+              *      timer_state = ACTIVE
+                          */
+	REQ_SENT,  /* Send completed for REQ
+              *      response is NULL
+              *      last_cmd = command issued
+              *      timer_state = ACTIVE
+                          */
+	RSP_RECEIVED,  /* Received Resp, but no Send completion yet
+              *      response is response buffer received
+              *      last_cmd = command issued
+              *      timer_state = ACTIVE
+                          */
+	REQ_COMPLETED,  /* all processing for REQ completed, ready to be gotten
+              *      response is response buffer received
+              *      last_cmd = command issued
+              *      timer_state = ACTIVE
+                          */
+	REQ_FAILED,  /* processing of REQ/RSP failed.
+              *      response is NULL
+              *      last_cmd = CMD_INVALID
+              *      timer_state = IDLE or EXPIRED
+              *      viport has been moved to error state to force recovery
+                          */
+};
+
 struct control {
 	struct viport			*parent;
 	struct control_config		*config;
@@ -63,11 +97,10 @@ struct control {
 	dma_addr_t			send_dma;
 	dma_addr_t			recv_dma;
 	enum control_timer_state	timer_state;
+	enum control_request_state      req_state;
 	struct timer_list		timer;
-	u8				req_retry_counter;
-	u8				req_outstanding;
 	u8				seq_num;
-	u8				rsp_expected;
+	u8				last_cmd;
 	struct recv_io			*response;
 	struct recv_io			*info;
 	struct list_head		failure_list;
diff --git a/drivers/infiniband/ulp/vnic/vnic_control_pkt.h b/drivers/infiniband/ulp/vnic/vnic_control_pkt.h
index a7d4fb9..6e875a8 100644
--- a/drivers/infiniband/ulp/vnic/vnic_control_pkt.h
+++ b/drivers/infiniband/ulp/vnic/vnic_control_pkt.h
@@ -62,6 +62,7 @@ enum {
 
 /* ptk_cmd values */
 enum {
+	CMD_INVALID		= 0,
 	CMD_INIT_VNIC		= 1,
 	CMD_CONFIG_DATA_PATH	= 2,
 	CMD_EXCHANGE_POOLS	= 3,



More information about the ewg mailing list