Commit edd572d7 authored by Felix Manlunas's avatar Felix Manlunas Committed by David S. Miller

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: default avatarWeilin Chang <weilin.chang@cavium.com>
Signed-off-by: default avatarFelix Manlunas <felix.manlunas@cavium.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6870957e
...@@ -198,14 +198,15 @@ int liquidio_set_feature(struct net_device *netdev, int cmd, u16 param1) ...@@ -198,14 +198,15 @@ int liquidio_set_feature(struct net_device *netdev, int cmd, u16 param1)
nctrl.ncmd.s.cmd = cmd; nctrl.ncmd.s.cmd = cmd;
nctrl.ncmd.s.param1 = param1; nctrl.ncmd.s.param1 = param1;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.wait_time = 100;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); 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", dev_err(&oct->pci_dev->dev, "Feature change failed in core (ret: 0x%x)\n",
ret); ret);
if (ret > 0)
ret = -EIO;
} }
return ret; return ret;
} }
...@@ -285,15 +286,7 @@ void liquidio_link_ctrl_cmd_completion(void *nctrl_ptr) ...@@ -285,15 +286,7 @@ void liquidio_link_ctrl_cmd_completion(void *nctrl_ptr)
struct octeon_device *oct = lio->oct_dev; struct octeon_device *oct = lio->oct_dev;
u8 *mac; u8 *mac;
if (nctrl->completion && nctrl->response_code) { if (nctrl->sc_status)
/* 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)
return; return;
switch (nctrl->ncmd.s.cmd) { switch (nctrl->ncmd.s.cmd) {
......
...@@ -472,12 +472,11 @@ lio_send_queue_count_update(struct net_device *netdev, uint32_t num_queues) ...@@ -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.param1 = num_queues;
nctrl.ncmd.s.param2 = num_queues; nctrl.ncmd.s.param2 = num_queues;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.wait_time = 100;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); 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", dev_err(&oct->pci_dev->dev, "Failed to send Queue reset command (ret: 0x%x)\n",
ret); ret);
return -1; return -1;
...@@ -708,13 +707,13 @@ static int octnet_gpio_access(struct net_device *netdev, int addr, int val) ...@@ -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.param1 = addr;
nctrl.ncmd.s.param2 = val; nctrl.ncmd.s.param2 = val;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.wait_time = 100;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
if (ret < 0) { if (ret) {
dev_err(&oct->pci_dev->dev, "Failed to configure gpio value\n"); dev_err(&oct->pci_dev->dev,
"Failed to configure gpio value, ret=%d\n", ret);
return -EINVAL; return -EINVAL;
} }
...@@ -734,13 +733,13 @@ static int octnet_id_active(struct net_device *netdev, int val) ...@@ -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.cmd = OCTNET_CMD_ID_ACTIVE;
nctrl.ncmd.s.param1 = val; nctrl.ncmd.s.param1 = val;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.wait_time = 100;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
if (ret < 0) { if (ret) {
dev_err(&oct->pci_dev->dev, "Failed to configure gpio value\n"); dev_err(&oct->pci_dev->dev,
"Failed to configure gpio value, ret=%d\n", ret);
return -EINVAL; return -EINVAL;
} }
...@@ -1412,7 +1411,6 @@ lio_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) ...@@ -1412,7 +1411,6 @@ lio_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
nctrl.ncmd.u64 = 0; nctrl.ncmd.u64 = 0;
nctrl.ncmd.s.cmd = OCTNET_CMD_SET_FLOW_CTL; nctrl.ncmd.s.cmd = OCTNET_CMD_SET_FLOW_CTL;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.wait_time = 100;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
...@@ -1433,8 +1431,9 @@ lio_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) ...@@ -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); ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
if (ret < 0) { if (ret) {
dev_err(&oct->pci_dev->dev, "Failed to set pause parameter\n"); dev_err(&oct->pci_dev->dev,
"Failed to set pause parameter, ret=%d\n", ret);
return -EINVAL; return -EINVAL;
} }
......
...@@ -2039,10 +2039,9 @@ static void liquidio_set_mcast_list(struct net_device *netdev) ...@@ -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 /* Apparently, any activity in this call from the kernel has to
* be atomic. So we won't wait for response. * be atomic. So we won't wait for response.
*/ */
nctrl.wait_time = 0;
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); 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", dev_err(&oct->pci_dev->dev, "DEVFLAGS change failed in core (ret: 0x%x)\n",
ret); ret);
} }
...@@ -2071,8 +2070,6 @@ static int liquidio_set_mac(struct net_device *netdev, void *p) ...@@ -2071,8 +2070,6 @@ static int liquidio_set_mac(struct net_device *netdev, void *p)
nctrl.ncmd.s.more = 1; nctrl.ncmd.s.more = 1;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
nctrl.wait_time = 100;
nctrl.udd[0] = 0; nctrl.udd[0] = 0;
/* The MAC Address is presented in network byte order. */ /* The MAC Address is presented in network byte order. */
...@@ -2083,6 +2080,14 @@ static int liquidio_set_mac(struct net_device *netdev, void *p) ...@@ -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"); dev_err(&oct->pci_dev->dev, "MAC Address change failed\n");
return -ENOMEM; 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(netdev->dev_addr, addr->sa_data, netdev->addr_len);
memcpy(((u8 *)&lio->linfo.hw_addr) + 2, addr->sa_data, ETH_ALEN); 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, ...@@ -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.cmd = OCTNET_CMD_ADD_VLAN_FILTER;
nctrl.ncmd.s.param1 = vid; nctrl.ncmd.s.param1 = vid;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.wait_time = 100;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); 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", dev_err(&oct->pci_dev->dev, "Add VLAN filter failed in core (ret: 0x%x)\n",
ret); ret);
if (ret > 0)
ret = -EIO;
} }
return ret; return ret;
...@@ -2651,14 +2657,15 @@ static int liquidio_vlan_rx_kill_vid(struct net_device *netdev, ...@@ -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.cmd = OCTNET_CMD_DEL_VLAN_FILTER;
nctrl.ncmd.s.param1 = vid; nctrl.ncmd.s.param1 = vid;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.wait_time = 100;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); 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", dev_err(&oct->pci_dev->dev, "Del VLAN filter failed in core (ret: 0x%x)\n",
ret); ret);
if (ret > 0)
ret = -EIO;
} }
return ret; return ret;
} }
...@@ -2684,15 +2691,16 @@ static int liquidio_set_rxcsum_command(struct net_device *netdev, int command, ...@@ -2684,15 +2691,16 @@ static int liquidio_set_rxcsum_command(struct net_device *netdev, int command,
nctrl.ncmd.s.cmd = command; nctrl.ncmd.s.cmd = command;
nctrl.ncmd.s.param1 = rx_cmd; nctrl.ncmd.s.param1 = rx_cmd;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.wait_time = 100;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
if (ret < 0) { if (ret) {
dev_err(&oct->pci_dev->dev, dev_err(&oct->pci_dev->dev,
"DEVFLAGS RXCSUM change failed in core(ret:0x%x)\n", "DEVFLAGS RXCSUM change failed in core(ret:0x%x)\n",
ret); ret);
if (ret > 0)
ret = -EIO;
} }
return ret; return ret;
} }
...@@ -2720,15 +2728,16 @@ static int liquidio_vxlan_port_command(struct net_device *netdev, int command, ...@@ -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.more = vxlan_cmd_bit;
nctrl.ncmd.s.param1 = vxlan_port; nctrl.ncmd.s.param1 = vxlan_port;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.wait_time = 100;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
if (ret < 0) { if (ret) {
dev_err(&oct->pci_dev->dev, dev_err(&oct->pci_dev->dev,
"VxLAN port add/delete failed in core (ret:0x%x)\n", "VxLAN port add/delete failed in core (ret:0x%x)\n",
ret); ret);
if (ret > 0)
ret = -EIO;
} }
return ret; return ret;
} }
...@@ -2851,6 +2860,7 @@ static int __liquidio_set_vf_mac(struct net_device *netdev, int vfidx, ...@@ -2851,6 +2860,7 @@ static int __liquidio_set_vf_mac(struct net_device *netdev, int vfidx,
struct lio *lio = GET_LIO(netdev); struct lio *lio = GET_LIO(netdev);
struct octeon_device *oct = lio->oct_dev; struct octeon_device *oct = lio->oct_dev;
struct octnic_ctrl_pkt nctrl; struct octnic_ctrl_pkt nctrl;
int ret = 0;
if (!is_valid_ether_addr(mac)) if (!is_valid_ether_addr(mac))
return -EINVAL; return -EINVAL;
...@@ -2864,12 +2874,13 @@ static int __liquidio_set_vf_mac(struct net_device *netdev, int vfidx, ...@@ -2864,12 +2874,13 @@ static int __liquidio_set_vf_mac(struct net_device *netdev, int vfidx,
nctrl.ncmd.s.cmd = OCTNET_CMD_CHANGE_MACADDR; nctrl.ncmd.s.cmd = OCTNET_CMD_CHANGE_MACADDR;
/* vfidx is 0 based, but vf_num (param1) is 1 based */ /* vfidx is 0 based, but vf_num (param1) is 1 based */
nctrl.ncmd.s.param1 = vfidx + 1; nctrl.ncmd.s.param1 = vfidx + 1;
nctrl.ncmd.s.param2 = (is_admin_assigned ? 1 : 0);
nctrl.ncmd.s.more = 1; nctrl.ncmd.s.more = 1;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; if (is_admin_assigned) {
nctrl.wait_time = LIO_CMD_WAIT_TM; nctrl.ncmd.s.param2 = true;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
}
nctrl.udd[0] = 0; nctrl.udd[0] = 0;
/* The MAC Address is presented in network byte order. */ /* 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, ...@@ -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]; 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) 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, ...@@ -2905,6 +2918,7 @@ static int liquidio_set_vf_vlan(struct net_device *netdev, int vfidx,
struct octeon_device *oct = lio->oct_dev; struct octeon_device *oct = lio->oct_dev;
struct octnic_ctrl_pkt nctrl; struct octnic_ctrl_pkt nctrl;
u16 vlantci; u16 vlantci;
int ret = 0;
if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs_alloced) if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs_alloced)
return -EINVAL; return -EINVAL;
...@@ -2936,13 +2950,17 @@ static int liquidio_set_vf_vlan(struct net_device *netdev, int vfidx, ...@@ -2936,13 +2950,17 @@ static int liquidio_set_vf_vlan(struct net_device *netdev, int vfidx,
nctrl.ncmd.s.more = 0; nctrl.ncmd.s.more = 0;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.cb_fn = NULL; 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; oct->sriov_info.vf_vlantci[vfidx] = vlantci;
return 0; return ret;
} }
static int liquidio_get_vf_config(struct net_device *netdev, int vfidx, 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, ...@@ -3063,6 +3081,7 @@ static int liquidio_set_vf_link_state(struct net_device *netdev, int vfidx,
struct lio *lio = GET_LIO(netdev); struct lio *lio = GET_LIO(netdev);
struct octeon_device *oct = lio->oct_dev; struct octeon_device *oct = lio->oct_dev;
struct octnic_ctrl_pkt nctrl; struct octnic_ctrl_pkt nctrl;
int ret = 0;
if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs_alloced) if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs_alloced)
return -EINVAL; return -EINVAL;
...@@ -3078,13 +3097,15 @@ static int liquidio_set_vf_link_state(struct net_device *netdev, int vfidx, ...@@ -3078,13 +3097,15 @@ static int liquidio_set_vf_link_state(struct net_device *netdev, int vfidx,
nctrl.ncmd.s.more = 0; nctrl.ncmd.s.more = 0;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.cb_fn = NULL; 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 static int
......
...@@ -1119,10 +1119,9 @@ static void liquidio_set_mcast_list(struct net_device *netdev) ...@@ -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 /* Apparently, any activity in this call from the kernel has to
* be atomic. So we won't wait for response. * be atomic. So we won't wait for response.
*/ */
nctrl.wait_time = 0;
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); 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", dev_err(&oct->pci_dev->dev, "DEVFLAGS change failed in core (ret: 0x%x)\n",
ret); ret);
} }
...@@ -1159,8 +1158,6 @@ static int liquidio_set_mac(struct net_device *netdev, void *p) ...@@ -1159,8 +1158,6 @@ static int liquidio_set_mac(struct net_device *netdev, void *p)
nctrl.ncmd.s.more = 1; nctrl.ncmd.s.more = 1;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
nctrl.wait_time = 100;
nctrl.udd[0] = 0; nctrl.udd[0] = 0;
/* The MAC Address is presented in network byte order. */ /* The MAC Address is presented in network byte order. */
...@@ -1171,6 +1168,7 @@ static int liquidio_set_mac(struct net_device *netdev, void *p) ...@@ -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"); dev_err(&oct->pci_dev->dev, "MAC Address change failed\n");
return -ENOMEM; return -ENOMEM;
} }
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
ether_addr_copy(((u8 *)&lio->linfo.hw_addr) + 2, addr->sa_data); 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, ...@@ -1664,8 +1662,6 @@ liquidio_vlan_rx_add_vid(struct net_device *netdev,
struct lio *lio = GET_LIO(netdev); struct lio *lio = GET_LIO(netdev);
struct octeon_device *oct = lio->oct_dev; struct octeon_device *oct = lio->oct_dev;
struct octnic_ctrl_pkt nctrl; struct octnic_ctrl_pkt nctrl;
struct completion compl;
u16 response_code;
int ret = 0; int ret = 0;
memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt)); memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
...@@ -1674,26 +1670,15 @@ liquidio_vlan_rx_add_vid(struct net_device *netdev, ...@@ -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.cmd = OCTNET_CMD_ADD_VLAN_FILTER;
nctrl.ncmd.s.param1 = vid; nctrl.ncmd.s.param1 = vid;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.wait_time = 100;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; 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); 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", dev_err(&oct->pci_dev->dev, "Add VLAN filter failed in core (ret: 0x%x)\n",
ret); 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 -EPERM;
}
return 0; return 0;
} }
...@@ -1713,14 +1698,15 @@ liquidio_vlan_rx_kill_vid(struct net_device *netdev, ...@@ -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.cmd = OCTNET_CMD_DEL_VLAN_FILTER;
nctrl.ncmd.s.param1 = vid; nctrl.ncmd.s.param1 = vid;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.wait_time = 100;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); 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", dev_err(&oct->pci_dev->dev, "Del VLAN filter failed in core (ret: 0x%x)\n",
ret); ret);
if (ret > 0)
ret = -EIO;
} }
return ret; return ret;
} }
...@@ -1746,14 +1732,15 @@ static int liquidio_set_rxcsum_command(struct net_device *netdev, int command, ...@@ -1746,14 +1732,15 @@ static int liquidio_set_rxcsum_command(struct net_device *netdev, int command,
nctrl.ncmd.s.cmd = command; nctrl.ncmd.s.cmd = command;
nctrl.ncmd.s.param1 = rx_cmd; nctrl.ncmd.s.param1 = rx_cmd;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.wait_time = 100;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); 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", dev_err(&oct->pci_dev->dev, "DEVFLAGS RXCSUM change failed in core (ret:0x%x)\n",
ret); ret);
if (ret > 0)
ret = -EIO;
} }
return ret; return ret;
} }
...@@ -1781,15 +1768,16 @@ static int liquidio_vxlan_port_command(struct net_device *netdev, int command, ...@@ -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.more = vxlan_cmd_bit;
nctrl.ncmd.s.param1 = vxlan_port; nctrl.ncmd.s.param1 = vxlan_port;
nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
nctrl.wait_time = 100;
nctrl.netpndev = (u64)netdev; nctrl.netpndev = (u64)netdev;
nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
if (ret < 0) { if (ret) {
dev_err(&oct->pci_dev->dev, dev_err(&oct->pci_dev->dev,
"DEVFLAGS VxLAN port add/delete failed in core (ret : 0x%x)\n", "DEVFLAGS VxLAN port add/delete failed in core (ret : 0x%x)\n",
ret); ret);
if (ret > 0)
ret = -EIO;
} }
return ret; return ret;
} }
......
...@@ -91,29 +91,6 @@ int octnet_send_nic_data_pkt(struct octeon_device *oct, ...@@ -91,29 +91,6 @@ int octnet_send_nic_data_pkt(struct octeon_device *oct,
ndata->reqtype); 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 static inline struct octeon_soft_command
*octnic_alloc_ctrl_pkt_sc(struct octeon_device *oct, *octnic_alloc_ctrl_pkt_sc(struct octeon_device *oct,
struct octnic_ctrl_pkt *nctrl) struct octnic_ctrl_pkt *nctrl)
...@@ -126,17 +103,14 @@ static inline struct octeon_soft_command ...@@ -126,17 +103,14 @@ static inline struct octeon_soft_command
uddsize = (u32)(nctrl->ncmd.s.more * 8); uddsize = (u32)(nctrl->ncmd.s.more * 8);
datasize = OCTNET_CMD_SIZE + uddsize; datasize = OCTNET_CMD_SIZE + uddsize;
rdatasize = (nctrl->wait_time) ? 16 : 0; rdatasize = 16;
sc = (struct octeon_soft_command *) sc = (struct octeon_soft_command *)
octeon_alloc_soft_command(oct, datasize, rdatasize, octeon_alloc_soft_command(oct, datasize, rdatasize, 0);
sizeof(struct octnic_ctrl_pkt));
if (!sc) if (!sc)
return NULL; return NULL;
memcpy(sc->ctxptr, nctrl, sizeof(struct octnic_ctrl_pkt));
data = (u8 *)sc->virtdptr; data = (u8 *)sc->virtdptr;
memcpy(data, &nctrl->ncmd, OCTNET_CMD_SIZE); memcpy(data, &nctrl->ncmd, OCTNET_CMD_SIZE);
...@@ -153,9 +127,8 @@ static inline struct octeon_soft_command ...@@ -153,9 +127,8 @@ static inline struct octeon_soft_command
octeon_prepare_soft_command(oct, sc, OPCODE_NIC, OPCODE_NIC_CMD, octeon_prepare_soft_command(oct, sc, OPCODE_NIC, OPCODE_NIC_CMD,
0, 0, 0); 0, 0, 0);
sc->callback = octnet_link_ctrl_callback; init_completion(&sc->complete);
sc->callback_arg = sc; sc->sc_status = OCTEON_REQUEST_PENDING;
sc->wait_time = nctrl->wait_time;
return sc; return sc;
} }
...@@ -198,5 +171,26 @@ octnet_send_nic_ctrl_pkt(struct octeon_device *oct, ...@@ -198,5 +171,26 @@ octnet_send_nic_ctrl_pkt(struct octeon_device *oct,
} }
spin_unlock_bh(&oct->cmd_resp_wqlock); 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; return retval;
} }
...@@ -52,20 +52,13 @@ struct octnic_ctrl_pkt { ...@@ -52,20 +52,13 @@ struct octnic_ctrl_pkt {
/** Input queue to use to send this command. */ /** Input queue to use to send this command. */
u64 iq_no; 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. */ /** The network device that issued the control command. */
u64 netpndev; u64 netpndev;
/** Callback function called when the command has been fetched */ /** Callback function called when the command has been fetched */
octnic_ctrl_pkt_cb_fn_t cb_fn; octnic_ctrl_pkt_cb_fn_t cb_fn;
u32 status; u32 sc_status;
u16 *response_code;
struct completion *completion;
}; };
#define MAX_UDD_SIZE(nctrl) (sizeof((nctrl)->udd)) #define MAX_UDD_SIZE(nctrl) (sizeof((nctrl)->udd))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment