1. Change struct octnic_ctrl_pkt to support synchronous operation.
2. Change code which use structure octnic_ctrl_pkt to send sc's
   synchronously.

Signed-off-by: Weilin Chang <weilin.ch...@cavium.com>
Signed-off-by: Felix Manlunas <felix.manlu...@cavium.com>
---
 drivers/net/ethernet/cavium/liquidio/lio_core.c    | 15 ++---
 drivers/net/ethernet/cavium/liquidio/lio_ethtool.c | 21 ++++---
 drivers/net/ethernet/cavium/liquidio/lio_main.c    | 69 ++++++++++++++--------
 drivers/net/ethernet/cavium/liquidio/lio_vf_main.c | 38 ++++--------
 drivers/net/ethernet/cavium/liquidio/octeon_nic.c  | 56 ++++++++----------
 drivers/net/ethernet/cavium/liquidio/octeon_nic.h  |  9 +--
 6 files changed, 98 insertions(+), 110 deletions(-)

diff --git a/drivers/net/ethernet/cavium/liquidio/lio_core.c 
b/drivers/net/ethernet/cavium/liquidio/lio_core.c
index 822ce0f..27b3655 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_core.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_core.c
@@ -198,14 +198,15 @@ int liquidio_set_feature(struct net_device *netdev, int 
cmd, u16 param1)
        nctrl.ncmd.s.cmd = cmd;
        nctrl.ncmd.s.param1 = param1;
        nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
-       nctrl.wait_time = 100;
        nctrl.netpndev = (u64)netdev;
        nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
 
        ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
-       if (ret < 0) {
+       if (ret) {
                dev_err(&oct->pci_dev->dev, "Feature change failed in core 
(ret: 0x%x)\n",
                        ret);
+               if (ret > 0)
+                       ret = -EIO;
        }
        return ret;
 }
@@ -285,15 +286,7 @@ void liquidio_link_ctrl_cmd_completion(void *nctrl_ptr)
        struct octeon_device *oct = lio->oct_dev;
        u8 *mac;
 
-       if (nctrl->completion && nctrl->response_code) {
-               /* Signal whoever is interested that the response code from the
-                * firmware has arrived.
-                */
-               WRITE_ONCE(*nctrl->response_code, nctrl->status);
-               complete(nctrl->completion);
-       }
-
-       if (nctrl->status)
+       if (nctrl->sc_status)
                return;
 
        switch (nctrl->ncmd.s.cmd) {
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c 
b/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c
index 8e05afd..d374c44 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c
@@ -472,12 +472,11 @@ lio_send_queue_count_update(struct net_device *netdev, 
uint32_t num_queues)
        nctrl.ncmd.s.param1 = num_queues;
        nctrl.ncmd.s.param2 = num_queues;
        nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
-       nctrl.wait_time = 100;
        nctrl.netpndev = (u64)netdev;
        nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
 
        ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
-       if (ret < 0) {
+       if (ret) {
                dev_err(&oct->pci_dev->dev, "Failed to send Queue reset command 
(ret: 0x%x)\n",
                        ret);
                return -1;
@@ -708,13 +707,13 @@ static int octnet_gpio_access(struct net_device *netdev, 
int addr, int val)
        nctrl.ncmd.s.param1 = addr;
        nctrl.ncmd.s.param2 = val;
        nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
-       nctrl.wait_time = 100;
        nctrl.netpndev = (u64)netdev;
        nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
 
        ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
-       if (ret < 0) {
-               dev_err(&oct->pci_dev->dev, "Failed to configure gpio value\n");
+       if (ret) {
+               dev_err(&oct->pci_dev->dev,
+                       "Failed to configure gpio value, ret=%d\n", ret);
                return -EINVAL;
        }
 
@@ -734,13 +733,13 @@ static int octnet_id_active(struct net_device *netdev, 
int val)
        nctrl.ncmd.s.cmd = OCTNET_CMD_ID_ACTIVE;
        nctrl.ncmd.s.param1 = val;
        nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
-       nctrl.wait_time = 100;
        nctrl.netpndev = (u64)netdev;
        nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
 
        ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
-       if (ret < 0) {
-               dev_err(&oct->pci_dev->dev, "Failed to configure gpio value\n");
+       if (ret) {
+               dev_err(&oct->pci_dev->dev,
+                       "Failed to configure gpio value, ret=%d\n", ret);
                return -EINVAL;
        }
 
@@ -1412,7 +1411,6 @@ lio_set_pauseparam(struct net_device *netdev, struct 
ethtool_pauseparam *pause)
        nctrl.ncmd.u64 = 0;
        nctrl.ncmd.s.cmd = OCTNET_CMD_SET_FLOW_CTL;
        nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
-       nctrl.wait_time = 100;
        nctrl.netpndev = (u64)netdev;
        nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
 
@@ -1433,8 +1431,9 @@ lio_set_pauseparam(struct net_device *netdev, struct 
ethtool_pauseparam *pause)
        }
 
        ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
-       if (ret < 0) {
-               dev_err(&oct->pci_dev->dev, "Failed to set pause parameter\n");
+       if (ret) {
+               dev_err(&oct->pci_dev->dev,
+                       "Failed to set pause parameter, ret=%d\n", ret);
                return -EINVAL;
        }
 
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c 
b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index 8ddc191..9c5a53d 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -2039,10 +2039,9 @@ static void liquidio_set_mcast_list(struct net_device 
*netdev)
        /* Apparently, any activity in this call from the kernel has to
         * be atomic. So we won't wait for response.
         */
-       nctrl.wait_time = 0;
 
        ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
-       if (ret < 0) {
+       if (ret) {
                dev_err(&oct->pci_dev->dev, "DEVFLAGS change failed in core 
(ret: 0x%x)\n",
                        ret);
        }
@@ -2071,8 +2070,6 @@ static int liquidio_set_mac(struct net_device *netdev, 
void *p)
        nctrl.ncmd.s.more = 1;
        nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
        nctrl.netpndev = (u64)netdev;
-       nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
-       nctrl.wait_time = 100;
 
        nctrl.udd[0] = 0;
        /* The MAC Address is presented in network byte order. */
@@ -2083,6 +2080,14 @@ static int liquidio_set_mac(struct net_device *netdev, 
void *p)
                dev_err(&oct->pci_dev->dev, "MAC Address change failed\n");
                return -ENOMEM;
        }
+
+       if (nctrl.sc_status) {
+               dev_err(&oct->pci_dev->dev,
+                       "%s: MAC Address change failed. sc return=%x\n",
+                        __func__, nctrl.sc_status);
+               return -EIO;
+       }
+
        memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
        memcpy(((u8 *)&lio->linfo.hw_addr) + 2, addr->sa_data, ETH_ALEN);
 
@@ -2623,14 +2628,15 @@ static int liquidio_vlan_rx_add_vid(struct net_device 
*netdev,
        nctrl.ncmd.s.cmd = OCTNET_CMD_ADD_VLAN_FILTER;
        nctrl.ncmd.s.param1 = vid;
        nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
-       nctrl.wait_time = 100;
        nctrl.netpndev = (u64)netdev;
        nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
 
        ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
-       if (ret < 0) {
+       if (ret) {
                dev_err(&oct->pci_dev->dev, "Add VLAN filter failed in core 
(ret: 0x%x)\n",
                        ret);
+               if (ret > 0)
+                       ret = -EIO;
        }
 
        return ret;
@@ -2651,14 +2657,15 @@ static int liquidio_vlan_rx_kill_vid(struct net_device 
*netdev,
        nctrl.ncmd.s.cmd = OCTNET_CMD_DEL_VLAN_FILTER;
        nctrl.ncmd.s.param1 = vid;
        nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
-       nctrl.wait_time = 100;
        nctrl.netpndev = (u64)netdev;
        nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
 
        ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
-       if (ret < 0) {
+       if (ret) {
                dev_err(&oct->pci_dev->dev, "Del VLAN filter failed in core 
(ret: 0x%x)\n",
                        ret);
+               if (ret > 0)
+                       ret = -EIO;
        }
        return ret;
 }
@@ -2684,15 +2691,16 @@ static int liquidio_set_rxcsum_command(struct 
net_device *netdev, int command,
        nctrl.ncmd.s.cmd = command;
        nctrl.ncmd.s.param1 = rx_cmd;
        nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
-       nctrl.wait_time = 100;
        nctrl.netpndev = (u64)netdev;
        nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
 
        ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
-       if (ret < 0) {
+       if (ret) {
                dev_err(&oct->pci_dev->dev,
                        "DEVFLAGS RXCSUM change failed in core(ret:0x%x)\n",
                        ret);
+               if (ret > 0)
+                       ret = -EIO;
        }
        return ret;
 }
@@ -2720,15 +2728,16 @@ static int liquidio_vxlan_port_command(struct 
net_device *netdev, int command,
        nctrl.ncmd.s.more = vxlan_cmd_bit;
        nctrl.ncmd.s.param1 = vxlan_port;
        nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
-       nctrl.wait_time = 100;
        nctrl.netpndev = (u64)netdev;
        nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
 
        ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
-       if (ret < 0) {
+       if (ret) {
                dev_err(&oct->pci_dev->dev,
                        "VxLAN port add/delete failed in core (ret:0x%x)\n",
                        ret);
+               if (ret > 0)
+                       ret = -EIO;
        }
        return ret;
 }
@@ -2851,6 +2860,7 @@ static int __liquidio_set_vf_mac(struct net_device 
*netdev, int vfidx,
        struct lio *lio = GET_LIO(netdev);
        struct octeon_device *oct = lio->oct_dev;
        struct octnic_ctrl_pkt nctrl;
+       int ret = 0;
 
        if (!is_valid_ether_addr(mac))
                return -EINVAL;
@@ -2864,12 +2874,13 @@ static int __liquidio_set_vf_mac(struct net_device 
*netdev, int vfidx,
        nctrl.ncmd.s.cmd = OCTNET_CMD_CHANGE_MACADDR;
        /* vfidx is 0 based, but vf_num (param1) is 1 based */
        nctrl.ncmd.s.param1 = vfidx + 1;
-       nctrl.ncmd.s.param2 = (is_admin_assigned ? 1 : 0);
        nctrl.ncmd.s.more = 1;
        nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
        nctrl.netpndev = (u64)netdev;
-       nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
-       nctrl.wait_time = LIO_CMD_WAIT_TM;
+       if (is_admin_assigned) {
+               nctrl.ncmd.s.param2 = true;
+               nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
+       }
 
        nctrl.udd[0] = 0;
        /* The MAC Address is presented in network byte order. */
@@ -2877,9 +2888,11 @@ static int __liquidio_set_vf_mac(struct net_device 
*netdev, int vfidx,
 
        oct->sriov_info.vf_macaddr[vfidx] = nctrl.udd[0];
 
-       octnet_send_nic_ctrl_pkt(oct, &nctrl);
+       ret = octnet_send_nic_ctrl_pkt(oct, &nctrl);
+       if (ret > 0)
+               ret = -EIO;
 
-       return 0;
+       return ret;
 }
 
 static int liquidio_set_vf_mac(struct net_device *netdev, int vfidx, u8 *mac)
@@ -2905,6 +2918,7 @@ static int liquidio_set_vf_vlan(struct net_device 
*netdev, int vfidx,
        struct octeon_device *oct = lio->oct_dev;
        struct octnic_ctrl_pkt nctrl;
        u16 vlantci;
+       int ret = 0;
 
        if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs_alloced)
                return -EINVAL;
@@ -2936,13 +2950,17 @@ static int liquidio_set_vf_vlan(struct net_device 
*netdev, int vfidx,
        nctrl.ncmd.s.more = 0;
        nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
        nctrl.cb_fn = NULL;
-       nctrl.wait_time = LIO_CMD_WAIT_TM;
 
-       octnet_send_nic_ctrl_pkt(oct, &nctrl);
+       ret = octnet_send_nic_ctrl_pkt(oct, &nctrl);
+       if (ret) {
+               if (ret > 0)
+                       ret = -EIO;
+               return ret;
+       }
 
        oct->sriov_info.vf_vlantci[vfidx] = vlantci;
 
-       return 0;
+       return ret;
 }
 
 static int liquidio_get_vf_config(struct net_device *netdev, int vfidx,
@@ -3063,6 +3081,7 @@ static int liquidio_set_vf_link_state(struct net_device 
*netdev, int vfidx,
        struct lio *lio = GET_LIO(netdev);
        struct octeon_device *oct = lio->oct_dev;
        struct octnic_ctrl_pkt nctrl;
+       int ret = 0;
 
        if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs_alloced)
                return -EINVAL;
@@ -3078,13 +3097,15 @@ static int liquidio_set_vf_link_state(struct net_device 
*netdev, int vfidx,
        nctrl.ncmd.s.more = 0;
        nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
        nctrl.cb_fn = NULL;
-       nctrl.wait_time = LIO_CMD_WAIT_TM;
 
-       octnet_send_nic_ctrl_pkt(oct, &nctrl);
+       ret = octnet_send_nic_ctrl_pkt(oct, &nctrl);
 
-       oct->sriov_info.vf_linkstate[vfidx] = linkstate;
+       if (!ret)
+               oct->sriov_info.vf_linkstate[vfidx] = linkstate;
+       else if (ret > 0)
+               ret = -EIO;
 
-       return 0;
+       return ret;
 }
 
 static int
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c 
b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
index 59c2dd9..f6bed6e 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
@@ -1119,10 +1119,9 @@ static void liquidio_set_mcast_list(struct net_device 
*netdev)
        /* Apparently, any activity in this call from the kernel has to
         * be atomic. So we won't wait for response.
         */
-       nctrl.wait_time = 0;
 
        ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
-       if (ret < 0) {
+       if (ret) {
                dev_err(&oct->pci_dev->dev, "DEVFLAGS change failed in core 
(ret: 0x%x)\n",
                        ret);
        }
@@ -1159,8 +1158,6 @@ static int liquidio_set_mac(struct net_device *netdev, 
void *p)
        nctrl.ncmd.s.more = 1;
        nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
        nctrl.netpndev = (u64)netdev;
-       nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
-       nctrl.wait_time = 100;
 
        nctrl.udd[0] = 0;
        /* The MAC Address is presented in network byte order. */
@@ -1171,6 +1168,7 @@ static int liquidio_set_mac(struct net_device *netdev, 
void *p)
                dev_err(&oct->pci_dev->dev, "MAC Address change failed\n");
                return -ENOMEM;
        }
+
        memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
        ether_addr_copy(((u8 *)&lio->linfo.hw_addr) + 2, addr->sa_data);
 
@@ -1664,8 +1662,6 @@ liquidio_vlan_rx_add_vid(struct net_device *netdev,
        struct lio *lio = GET_LIO(netdev);
        struct octeon_device *oct = lio->oct_dev;
        struct octnic_ctrl_pkt nctrl;
-       struct completion compl;
-       u16 response_code;
        int ret = 0;
 
        memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
@@ -1674,26 +1670,15 @@ liquidio_vlan_rx_add_vid(struct net_device *netdev,
        nctrl.ncmd.s.cmd = OCTNET_CMD_ADD_VLAN_FILTER;
        nctrl.ncmd.s.param1 = vid;
        nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
-       nctrl.wait_time = 100;
        nctrl.netpndev = (u64)netdev;
        nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
-       init_completion(&compl);
-       nctrl.completion = &compl;
-       nctrl.response_code = &response_code;
 
        ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
-       if (ret < 0) {
+       if (ret) {
                dev_err(&oct->pci_dev->dev, "Add VLAN filter failed in core 
(ret: 0x%x)\n",
                        ret);
-               return -EIO;
-       }
-
-       if (!wait_for_completion_timeout(&compl,
-                                        msecs_to_jiffies(nctrl.wait_time)))
-               return -EPERM;
-
-       if (READ_ONCE(response_code))
                return -EPERM;
+       }
 
        return 0;
 }
@@ -1713,14 +1698,15 @@ liquidio_vlan_rx_kill_vid(struct net_device *netdev,
        nctrl.ncmd.s.cmd = OCTNET_CMD_DEL_VLAN_FILTER;
        nctrl.ncmd.s.param1 = vid;
        nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
-       nctrl.wait_time = 100;
        nctrl.netpndev = (u64)netdev;
        nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
 
        ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
-       if (ret < 0) {
+       if (ret) {
                dev_err(&oct->pci_dev->dev, "Del VLAN filter failed in core 
(ret: 0x%x)\n",
                        ret);
+               if (ret > 0)
+                       ret = -EIO;
        }
        return ret;
 }
@@ -1746,14 +1732,15 @@ static int liquidio_set_rxcsum_command(struct 
net_device *netdev, int command,
        nctrl.ncmd.s.cmd = command;
        nctrl.ncmd.s.param1 = rx_cmd;
        nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
-       nctrl.wait_time = 100;
        nctrl.netpndev = (u64)netdev;
        nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
 
        ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
-       if (ret < 0) {
+       if (ret) {
                dev_err(&oct->pci_dev->dev, "DEVFLAGS RXCSUM change failed in 
core (ret:0x%x)\n",
                        ret);
+               if (ret > 0)
+                       ret = -EIO;
        }
        return ret;
 }
@@ -1781,15 +1768,16 @@ static int liquidio_vxlan_port_command(struct 
net_device *netdev, int command,
        nctrl.ncmd.s.more = vxlan_cmd_bit;
        nctrl.ncmd.s.param1 = vxlan_port;
        nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
-       nctrl.wait_time = 100;
        nctrl.netpndev = (u64)netdev;
        nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
 
        ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
-       if (ret < 0) {
+       if (ret) {
                dev_err(&oct->pci_dev->dev,
                        "DEVFLAGS VxLAN port add/delete failed in core (ret : 
0x%x)\n",
                        ret);
+               if (ret > 0)
+                       ret = -EIO;
        }
        return ret;
 }
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_nic.c 
b/drivers/net/ethernet/cavium/liquidio/octeon_nic.c
index b7364bb..676fe0b 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_nic.c
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_nic.c
@@ -91,29 +91,6 @@ int octnet_send_nic_data_pkt(struct octeon_device *oct,
                                   ndata->reqtype);
 }
 
-static void octnet_link_ctrl_callback(struct octeon_device *oct,
-                                     u32 status,
-                                     void *sc_ptr)
-{
-       struct octeon_soft_command *sc = (struct octeon_soft_command *)sc_ptr;
-       struct octnic_ctrl_pkt *nctrl;
-
-       nctrl = (struct octnic_ctrl_pkt *)sc->ctxptr;
-
-       /* Call the callback function if status is zero (meaning OK) or status
-        * contains a firmware status code bigger than zero (meaning the
-        * firmware is reporting an error).
-        * If no response was expected, status is OK if the command was posted
-        * successfully.
-        */
-       if ((!status || status > FIRMWARE_STATUS_CODE(0)) && nctrl->cb_fn) {
-               nctrl->status = status;
-               nctrl->cb_fn(nctrl);
-       }
-
-       octeon_free_soft_command(oct, sc);
-}
-
 static inline struct octeon_soft_command
 *octnic_alloc_ctrl_pkt_sc(struct octeon_device *oct,
                          struct octnic_ctrl_pkt *nctrl)
@@ -126,17 +103,14 @@ static inline struct octeon_soft_command
        uddsize = (u32)(nctrl->ncmd.s.more * 8);
 
        datasize = OCTNET_CMD_SIZE + uddsize;
-       rdatasize = (nctrl->wait_time) ? 16 : 0;
+       rdatasize = 16;
 
        sc = (struct octeon_soft_command *)
-               octeon_alloc_soft_command(oct, datasize, rdatasize,
-                                         sizeof(struct octnic_ctrl_pkt));
+               octeon_alloc_soft_command(oct, datasize, rdatasize, 0);
 
        if (!sc)
                return NULL;
 
-       memcpy(sc->ctxptr, nctrl, sizeof(struct octnic_ctrl_pkt));
-
        data = (u8 *)sc->virtdptr;
 
        memcpy(data, &nctrl->ncmd, OCTNET_CMD_SIZE);
@@ -153,9 +127,8 @@ static inline struct octeon_soft_command
        octeon_prepare_soft_command(oct, sc, OPCODE_NIC, OPCODE_NIC_CMD,
                                    0, 0, 0);
 
-       sc->callback = octnet_link_ctrl_callback;
-       sc->callback_arg = sc;
-       sc->wait_time = nctrl->wait_time;
+       init_completion(&sc->complete);
+       sc->sc_status = OCTEON_REQUEST_PENDING;
 
        return sc;
 }
@@ -198,5 +171,26 @@ octnet_send_nic_ctrl_pkt(struct octeon_device *oct,
        }
 
        spin_unlock_bh(&oct->cmd_resp_wqlock);
+
+       switch (nctrl->ncmd.s.cmd) {
+               /* caller holds lock, can not sleep */
+       case OCTNET_CMD_CHANGE_DEVFLAGS:
+       case OCTNET_CMD_SET_MULTI_LIST:
+       case OCTNET_CMD_SET_UC_LIST:
+               WRITE_ONCE(sc->caller_is_done, true);
+               return retval;
+       }
+
+       retval = wait_for_sc_completion_timeout(oct, sc, 0);
+       if (retval)
+               return (retval);
+
+       nctrl->sc_status = sc->sc_status;
+       retval = nctrl->sc_status;
+       if (nctrl->cb_fn)
+               nctrl->cb_fn(nctrl);
+
+       WRITE_ONCE(sc->caller_is_done, true);
+
        return retval;
 }
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_nic.h 
b/drivers/net/ethernet/cavium/liquidio/octeon_nic.h
index de4130d..87dd6f8 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_nic.h
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_nic.h
@@ -52,20 +52,13 @@ struct octnic_ctrl_pkt {
        /** Input queue to use to send this command. */
        u64 iq_no;
 
-       /** Time to wait for Octeon software to respond to this control command.
-        *  If wait_time is 0, OSI assumes no response is expected.
-        */
-       size_t wait_time;
-
        /** The network device that issued the control command. */
        u64 netpndev;
 
        /** Callback function called when the command has been fetched */
        octnic_ctrl_pkt_cb_fn_t cb_fn;
 
-       u32 status;
-       u16 *response_code;
-       struct completion *completion;
+       u32 sc_status;
 };
 
 #define MAX_UDD_SIZE(nctrl) (sizeof((nctrl)->udd))
-- 
2.9.0

Reply via email to