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 <[EMAIL PROTECTED]>
Signed-off-by: Ramachandra K <[EMAIL PROTECTED]>
---

 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,
_______________________________________________
ewg mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ewg

Reply via email to