aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/cavium
diff options
context:
space:
mode:
authorFelix Manlunas <felix.manlunas@cavium.com>2018-08-28 18:51:40 -0700
committerDavid S. Miller <davem@davemloft.net>2018-08-29 20:07:41 -0700
commitedd572d72f8c6d7179c3943edaea3bcfee9484f5 (patch)
treef2a83a4f9097f6903cb034ecb9f395b01c3e5b02 /drivers/net/ethernet/cavium
parentliquidio: make soft command calls synchronous (diff)
downloadlinux-dev-edd572d72f8c6d7179c3943edaea3bcfee9484f5.tar.xz
linux-dev-edd572d72f8c6d7179c3943edaea3bcfee9484f5.zip
liquidio: change octnic_ctrl_pkt to do synchronous soft commands
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.chang@cavium.com> Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/cavium')
-rw-r--r--drivers/net/ethernet/cavium/liquidio/lio_core.c15
-rw-r--r--drivers/net/ethernet/cavium/liquidio/lio_ethtool.c21
-rw-r--r--drivers/net/ethernet/cavium/liquidio/lio_main.c69
-rw-r--r--drivers/net/ethernet/cavium/liquidio/lio_vf_main.c38
-rw-r--r--drivers/net/ethernet/cavium/liquidio/octeon_nic.c56
-rw-r--r--drivers/net/ethernet/cavium/liquidio/octeon_nic.h9
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 822ce0f5905d..27b3655912be 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 8e05afd5e39c..d374c44dfcac 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 8ddc191a9271..9c5a53d74dd1 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 59c2dd92aac5..f6bed6ebb344 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 b7364bb3b186..676fe0b7ab8c 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 de4130d26a98..87dd6f89ce51 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))